I'm trying to make a news table, with the latest news from my site.
In my news site, I only want to show the first 20 words from the table (with a "Read more")
I'm selecting my table like this:
cmd.CommandText = "SELECT news.*, login.firstname, login.lastname, login.pisture AS picture FROM news LEFT JOIN login ON login.Id = nyheder.writer ORDER BY news.Id DESC";
If you use sql server, try to add SUBSTRING ( expression ,start , length ) to your query:
e.g. if you want to get the 20 characters from the "content" field in "news" table:
SELECT news.*,
SUBSTRING ( news.content, 1, 20) as short_content ,
login.firstname, login.lastname,
login.pisture AS picture
FROM news LEFT JOIN login ON login.Id = nyheder.writer
ORDER BY news.Id DESC
If you use another database like oracle try "substr".
Usually to retrieve a short part of a long text in database, you should use a string function like as this:
SELECT LEFT(news.newsText, 20)+"..." as shortText ,... from ...
the LEFT function works in SqlServer and Ms Access database. for other databases there is an equivalent function. if you want you can check also the length of news content and add the "..." trailing string only if it is trimmed.
Related
I am issuing an SQL query in my visual studio application to search a database. I am having trouble joining two tables into one query search. I am looking to combine the First and Last name of an employee and match it up to a phone number. In one table I have an abbreviated name, and on the other table I have the full name.
Example
Code
cmdTxt.Append("SELECT partner.staffid, staff.Forename,staff.surname FROM tblpartner LEFT JOIN tblstaff ON staff.StaffID = partner.staffid ORDER BY staff.forename , staff.surname ");
I would Like to have a field that shows the Forename , surename, and phone number in one query search
You are using "partner" and "staff" as table aliases, but you aren't assigning those aliases to the table names. If you want to use those instead of the full table names, you need:
SELECT partner.staffid, staff.Forename,staff.surname, partner.phone
FROM tblpartner partner
LEFT JOIN tblstaff staff ON staff.StaffID = partner.staffid
ORDER BY staff.forename , staff.surname
As general advice, get your query working outside of your string literal; enter it into SQL Server Management Studio or something similar. Had you done that, it should have clearly showed you what the problem was. Then when you have your query set how you want, you can copy it into your Command Text in your Visual Studio application.
I have a sql (transact sql - SQL server 2012) which used to fetch names of customers from a table (Customer) who has valid addresses (from table Details):
Select Customer.Name, Details.Address
from Customer
left outer join Details on Details.Customer = Customer.Name
This used to send back each record (name) row for each customer every time from the db server. No multiple records are fetched.
Recently I needed to modify this sql text in order to fetch even the name of the books they have borrowed as per the database, which is saved in another table (Lending). Now the script looks like:
Select Customer.Name, Details.Address, Lending.BookName
from Customer
left outer join Details on Details.Customer = Customer.Name
left outer join Lending on Lending.CustomerName = Customer.Name
It is returning the records properly, but now I have got a problem. Since a customer can borrow multiple books, the returned data has multiple rows for the same customer showing multiple book names. According to my software specification I need to fetch one line for each customer and in that one row i need to append all the book names in a single column.
Can someone help me with this: How to append multiple data for same record in a single column such as:
Name Address BookName
Somdip XX Brief History of Time,Headfirst SQL,Headfirst C#
instead of
Name Address BookName
Somdip XX Brief History of Time
Somdip XX Headfirst SQL
Somdip XX Headfirst C#
??
I used the above sql text with 'where' and 'order by' clauses such as :
SELECT Name,
Address ,
Split.a.value('.', 'VARCHAR(100)') BookName
FROM (SELECT Name,
Address ,
Cast ('<M>' + Replace(BookName, ',', '</M><M>') + '</M>' AS XML) AS Data
FROM [table] where ID = '1' order by Name) AS A
CROSS APPLY Data.nodes ('/M') AS Split(a)
and it is giving me an error: The ORDER BY clause is invalid in views, inline functions, derived tables, subqueries, and common table expressions, unless TOP, OFFSET or FOR XML is also specified.
try this:
SELECT Name,
Address ,
Split.a.value('.', 'VARCHAR(100)') BookName
FROM (SELECT Name,
Address ,
Cast ('<M>' + Replace(BookName, ',', '</M><M>') + '</M>' AS XML) AS Data
FROM [table]) AS A
CROSS APPLY Data.nodes ('/M') AS Split(a)
While I think this is generally a bad idea - returning multiple data items in a single cell - there are a number of ways to go about it, with different performance concerns.
What you're looking for is here: Concatenate many rows into a single text string?
Can someone please share with me a good approach on how to build a query that uses one text box with multiple keywords that pick columns on several DB tables. Please see attached screen shot.
Requirement
I will need to define a format rule so the user "must" enter an input search with the following format: [category], [suburb] [postcode]. The code behind logic (web API) can then parse this input (this is where my search query will be parsed).
If you expect unified output then you can use UNION
INSERT INTO #resultTable
SELECT serviceid
FROM (
SELECT DISTINCT serviceid
FROM addresses s
WHERE s.suburb = #criteria
OR s.postal = #criteria
UNION
SELECT DISTINCT serviceid
FROM categories c
WHERE c.categotyName = #criteria
)
SELECT *
FROM services s INNER JOIN #resultTable ON ...
I've a varbinary column profile_name in my accounts table. Initially, I thought my users will not enter special characters and will keep it short and sweet.
But, that was my terrible mistake. They started keeping long profile names with lots of special characters, which is causing me trouble.
Now, I've limited their options to alphanumerics, underscore and hyphen and should be 3 to 10 characters. In other words this regex: [\w-]{3,10}
The task is uphill now.
I've 570 users already and I want to update their profile names to fit into the above rules.
I've some barebone code:
public NpMaintainance()
{
UTF8Encoder encode = new UTF8Encoder();
List<string> names = new List<string>();
using (con)
{
con.Open();
using (cmd)
{
cmd.Parameters.Clear();
cmd.Connection = con;
cmd.CommandText = "select profile_name from accounts";
using (dr = cmd.ExecuteReader())
{
names.Add((dr[0] as byte[]).ToUnicodeString(encode));
}
}
}
}
I've just the code, which I've not tried, because it is a production site. Now names contains the profile names, which I've to reinsert into the table. And to add to my problem, profile_name is unique, so no two names should be same.
I've provided all the details I could, and hoping to get an answer!
What should I do? Is there any other way(using only sql?), or if not please help me with the way I'm currently doing!
UPDATE:
Here is MySQL version, with the help of cleanString function written by Shay Anderson with just a minor change to accept numbers an letters.
IF ASCII(c) > 31 AND ASCII(c) < 127 THEN
replaced with
IF (ASCII(c) > 47 AND ASCII(c) < 57)
OR (ASCII(c) > 64 AND ASCII(c) < 91)
OR (ASCII(c) > 96 AND ASCII(c) < 122) THEN
The basic idea is the same create a temp table with profile_name converted to varchar, cleaning it and updateing it back to accounts table.
-- for testing purposes create and populate test table
CREATE TABLE accounts(id INT, profile_name VARBINARY(8000));
INSERT INTO accounts(id, profile_name)
SELECT 1, CAST('User|%$&&/(/' AS BINARY);
-- check what's in there
SELECT id, profile_name, CAST(profile_name AS CHAR) FROM accounts;
CREATE TEMPORARY TABLE IF NOT EXISTS tmp_accounts AS (
SELECT id, profile_name, CAST(profile_name AS CHAR) AS 'converted_name'
FROM accounts
);
-- clean converted profile_name in temp table using function udf_cleanString
UPDATE tmp_accounts
SET converted_name = UDF_CLEANSTRING(converted_name);
/* do any other change necessary.... length etc.
when satisfied with changes in temp table update accounts table with new profile_name
*/
UPDATE accounts a
INNER JOIN tmp_accounts t ON t.id = a.id
SET a.profile_name = CAST(t.converted_name AS BINARY);
-- check what was done with profile_name after changes
SELECT id, profile_name, CAST(profile_name AS CHAR) FROM accounts;
-- DROP TABLE tmp_accounts
In SQL you could try converting varbinary(max) to nvarchar(max) type something like this (assuming accountid is primary key of accounts table)
SELECT accountid, profile_name, CONVERT(NVARCHAR(MAX),profile_name) as converted_name
INTO #tmpaccounts
FROM accounts
then use some character stripping function like the one from How to strip all non-alphabetic characters from string in SQL Server?. It might need some tweaking to allow hyphens and underscores, but it shouldn't be too hard
UPDATE #tmpaccounts SET converted_name = [dbo].[RemoveNonAlphaCharacters](converted_name)
that should take care of the character limitations, if you have longer profile names then 10 trim them, hopefully there shouldn't be a lot of them. (I'm am somewhat skeptical of changing profile names without permission or at least awareness from the account owners)
After that you can update the accounts table from #tmpaccounts.
UPDATE a
SET profile_name = CONVERT(VARBINARY(max), converted_name)
FROM accounts a
INNER JOIN #tmpaccounts t on t.accountid = a.accountid
Of course DON'T do this on production database, use demo or training DB.
sqlmysql
I have a List of UserID's and a open connection to SQL Server. How can I loop through this List and Select matching UserID with First_Name and Last_Name columns? I assume the output can be in a datatable?
many thanks
It varies slightly depending on which type of SQL you're running, but this and this should get you started.
The most expedient way of doing this would be to:
Turn the List into a string containing a comma separated list of the userid values
Supply that CSV string into an IN clause, like:
SELECT u.first_name,
u.last_name
FROM USER_TABLE u
WHERE u.userid IN ([comma separated list of userids])
Otherwise, you could insert the values into a temp table and join to the users table:
SELECT u.first_name,
u.last_name
FROM USER_TABLE u
JOIN #userlist ul ON ul.userid = u.userid
Write a function in your SQL database named ParseIntegerArray. This should convert a comma delimited string into a table of IDs, you can then join to this in your query. This also helps to avoid any SQL injection risk you could get from concatenating strings to build SQL. You can also use this function when working with LINQ to SQL or LINQ to Entities.
DECLARE #itemIds nvarchar(max)
SET itemIds = '1,2,3'
SELECT
i.*
FROM
dbo.Item AS i
INNER JOIN dbo.ParseIntegerArray(#itemIds) AS id ON i.ItemId = id.Id
This article should help you: http://msdn.microsoft.com/en-us/library/aa496058%28SQL.80%29.aspx
I've used this in the past to create a stored procedure accepting a single comma delimited varchar parameter.
My source from the C# program was a checked list box, and I built the comma delimited string using a foreach loop and a StringBuilder to do the concatenation. There might be better methods, depending on the number of items you have in your list though.
To come back to the SQL part, the fn_Split function discussed in the article, enables you to transform the comma delimited string back to a table variable that SQL Server can understand... and which you can query in your stored procedure.
Here is an example:
CREATE PROCEDURE GetSelectedItems
(
#SelectedItemsID Varchar(MAX) -- comma-separated string containing the items to select
)
AS
SELECT * FROM Items
WHERE ItemID IN (SELECT Value FROM dbo.fn_Split(#SelectedItemsIDs,','))
RETURN
GO
Note that you could also use an inner join, instead of the IN() if you prefer.
If you don't have the fn_Split UDF on your SQL Server, you can find it here: http://odetocode.com/Articles/365.aspx
I hope this helps.