Order By for NVARCHAR column in SQL Server - sql

I have a NVARCHAR(255) column in a SQL Server 2005 that contain either letters or numbers.
Declare #Temp Table(Name NVARCHAR(255))
Insert Into #Temp Values('1')
Insert Into #Temp Values('2')
Insert Into #Temp Values('3')
Insert Into #Temp Values('10')
Insert Into #Temp Values('aaaa')
Insert Into #Temp Values('ccaaaaa')
Insert Into #Temp Values('cca')
Insert Into #Temp Values('cccc')
Insert Into #Temp Values('ccaa')
Select * From #Temp Order by Name
This query returns bad result. Can somebody explain why?
Also, can somebody tell me which query to use to sort values.
I want to get next sequence:
1
2
3
10
aaaa
cca
ccaa
ccaaaaa
cccc
Thanks

#Shark showed you why, I'll show you a work around in your SELECT to get you the results you want:
Select * From #Temp
Order by
case isnumeric(name)
when 1 then cast(name as int)
else 999999999999999 end,
name

The actual order of results will be this:
1
10
2
3
aaaa
cca
ccaa
ccaaaaa
cccc
And SQL Server is sorting it like that because it is getting sorted based on their character values. In other words, the character 1 comes before 2, as 10 will also come before 2.
So the reason you're getting odd sorting is because your are ordering by string values, not numeric.
EDIT: Please see Adrian's answer to the workaround.

Related

SQL to combine results into one group in the where clause

I have a query
SELECT name,
COUNT (name)
FROM employee
WHERE LOCATION IS LIKE (%%NY%%)
GROUP BY name
name coount
alex m 10
alex.m 5
alex.ma 1
alex 500
How can I combine all the alex's into just one Alex
so that I get the output as
name count
alex 516
I need something like if it matches alex%% then consider it as alex
Here is your dynamic solution on the below for SQL Server.
First, let's see the sample data I worked on:
create table #temp
(name varchar(20))
insert into #temp values ('jack')
insert into #temp values ('jack rx')
insert into #temp values ('jack.a')
insert into #temp values ('jack.bb')
insert into #temp values ('jack.xy')
insert into #temp values ('brandon.12')
insert into #temp values ('brandon')
insert into #temp values ('brandon.k7s')
insert into #temp values ('brandon.bg')
insert into #temp values ('Jonathan')
Then, we need to employ string operators:
;with cte (name, charin, charin_space) as
(
select name,CHARINDEX('.',name,0) as charin, CHARINDEX(' ',name,0) as charin_space
from #temp
)
select name,(case when charin = 0 and charin_space = 0 then name
when charin = 0 and charin_space <> 0 then SUBSTRING(name,0,charin_space)
when charin <> 0 and charin_space = 0 then SUBSTRING(name,0,charin)
end) as mainName
into #temp2
from cte
The temp table #temp2 has the names only like jack, brandon and jonathan. All we need is to connect those tables now and use group by like:
select t2.MainName,COUNT(t2.MainName)
from #temp t1
inner join #temp2 t2 on t1.name = t2.name
group by t2.mainName
I hope it helps!
You need to get part of the name. But this only work for SQL Server. You don't specify which dbms you are using. The query works with your example, but it will also pick up Alexa, Alexander, ...
SELECT LEFT(name, 4),
SUM(coount)
FROM employee
WHERE LOCATION IS LIKE (%%NY%%)
GROUP BY LEFT(name, 4)

Concatenate Rows in SQL with Different values [duplicate]

This question already has answers here:
Concatenate column values for rows with the same values (of different columns)
(3 answers)
Closed 8 years ago.
Hello I have an issue concatinating multiple rows in different tables adding a field separator ; For example. Basically I want to concatenate all values that has the same DocumentsID and they have to have to have different fieldid. If it doesn't have fieldid just leave it blank. Hopefully that makes sense. First time asking here. Thanks again.
DocumentsID Field ID Values
1 190 Jordan
1 191 Kobe
1 192 Rose
2 191 Kobe
Expected Results
DocumentsID Values
1 Jordan; Kobe; Rose
2 Kobe
There's a same question here that you can refer.
I've modified the query used in the accepted answer just to fit in your example.
set nocount on;
declare #YourTable table (DocumentID int, FieldID int, [Values] varchar(50))
insert into #YourTable VALUES (1,190,'Jordan')
insert into #YourTable VALUES (1,191,'Kobe')
insert into #YourTable VALUES (1,192,'Rose')
insert into #YourTable VALUES (2,191,'Kobe')
set nocount off
SELECT DISTINCT
t1.DocumentID
,STUFF(
(SELECT
', ' + t2.[Values]
FROM #YourTable t2
WHERE t1.DocumentID=t2.DocumentID
ORDER BY t2.[Values]
FOR XML PATH(''), TYPE
).value('.','varchar(max)')
,1,2, ''
) AS [Values]
FROM #YourTable t1
GROUP BY t1.DocumentID,t1.[Values]

T-SQL Insert Column from Other Table

Hello I am trying to insert values from one table column to another table. I am using SQL Server 2008 R2. Here is example:
Table 1
Declare #Table1 table (file varchar(15), type int, partiesid int)
Table 2
Declare #Table2 table (file varchar(15), ....many other columns)
I would like to insert file from Table 2 into Table 1 as well as some other static values.
So select * from table1 would end up looking like this:
File Type PartiesID
GW100 1 555
GW101 1 555
GW103 1 555
GW104 1 555
where the GW100, GW101, etc come from table2 and the 1 and 555 are static for every row.
I tried insert into table1 (file,type,partiesid) values (select file from table2,1,555) but that doesn't work. Is there a way where it will just insert a row for each unique file and also insert the static fields of 1 and 555 as separate columns?
Thanks!
Insert into #table2
(
file,
type,
partiesid,
...(other columns for which you need to give static values)
)
select
file,
type,
partiesid,
...(static values for columns)
from #table1
You can try the below query:
USE dbName
GO
INSERT INTO table2 (column_name(s))
SELECT column_name(s) FROM table1;
GO

INSERT INTO With a SubQuery and some operations

I'm trying to insert some data to a table contains two things : "a string" and "maximum number in Order column + 1".
This is my query:
INSERT INTO MyTable ([Text],[Order])
SELECT 'MyText' , (Max([Order]) + 1)
FROM MyTable
What is going wrong with my query?
I'm using Microsoft SQL Server 2005 SP3.
You can test this query like this:
I don't receive error:
create table #MyTable
(
[Text] varchar(40),
[Order] int NOT NULL
)
INSERT INTO #MyTable([Text],[Order])
SELECT 'MyText' [Text], isnull(max([order]) + 1, 0) [Order]
FROM #MyTable
drop table #MyTable
Original:
INSERT INTO MyTable ([Text],[Order])
SELECT 'MyText' [Text], max([Order]) + 1 [Order]
FROM MyTable
or
INSERT INTO MyTable ([Text],[Order])
SELECT top 1 'MyText' [Text], max([Order]) + 1 [Order]
FROM MyTable
limit is not valid in SQL Server as far as I know.
Cannot insert the value NULL into column 'Order', table 'master.dbo.MyTable'; column does not allow nulls. INSERT fails. The statement has been terminated.
This means that the Order column isn't allowed to be null, and that the Max([Order]) + 1 part of your column returns NULL.
This is because your table is empty, as you already noticed by yourself.
You can work around this by replacing NULL by a real number in the query, using ISNULL():
INSERT INTO MyTable ([Text],[Order])
SELECT 'MyText' , (isnull(Max([Order]),0) + 1)
FROM MyTable
Unless he has a column named OrderBy
then he would have to add / assign all values within that Insert especially if the column does not allow for nulls
sounds like fully qualifying the Insert with the dbo.MyTable.Field may make more sense.
also why are you naming fields with SQL Key words...???
INSERT INTO MyTable ([Text],[Order] Values('MyTextTest',1)
try a test insert first..

Select records with order of IN clause

I have
SELECT * FROM Table1 WHERE Col1 IN(4,2,6)
I want to select and return the records with the specified order which i indicate in the IN clause
(first display record with Col1=4, Col1=2, ...)
I can use
SELECT * FROM Table1 WHERE Col1 = 4
UNION ALL
SELECT * FROM Table1 WHERE Col1 = 6 , .....
but I don't want to use that, cause I want to use it as a stored procedure and not auto generated.
I know it's a bit late but the best way would be
SELECT *
FROM Table1
WHERE Col1 IN( 4, 2, 6 )
ORDER BY CHARINDEX(CAST(Col1 AS VARCHAR), '4,2,67')
Or
SELECT CHARINDEX(CAST(Col1 AS VARCHAR), '4,2,67')s_order,
*
FROM Table1
WHERE Col1 IN( 4, 2, 6 )
ORDER BY s_order
You have a couple of options. Simplest may be to put the IN parameters (they are parameters, right) in a separate table in the order you receive them, and ORDER BY that table.
The solution is along this line:
SELECT * FROM Table1
WHERE Col1 IN(4,2,6)
ORDER BY
CASE Col1
WHEN 4 THEN 1
WHEN 2 THEN 2
WHEN 6 THEN 3
END
select top 0 0 'in', 0 'order' into #i
insert into #i values(4,1)
insert into #i values(2,2)
insert into #i values(6,3)
select t.* from Table1 t inner join #i i on t.[in]=t.[col1] order by i.[order]
Replace the IN values with a table, including a column for sort order to used in the query (and be sure to expose the sort order to the calling application):
WITH OtherTable (Col1, sort_seq)
AS
(
SELECT Col1, sort_seq
FROM (
VALUES (4, 1),
(2, 2),
(6, 3)
) AS OtherTable (Col1, sort_seq)
)
SELECT T1.Col1, O1.sort_seq
FROM Table1 AS T1
INNER JOIN OtherTable AS O1
ON T1.Col1 = O1.Col1
ORDER
BY sort_seq;
In your stored proc, rather than a CTE, split the values into table (a scratch base table, temp table, function that returns a table, etc) with the sort column populated as appropriate.
I have found another solution. It's similar to the answer from onedaywhen, but it's a little shorter.
SELECT sort.n, Table1.Col1
FROM (VALUES (4), (2), (6)) AS sort(n)
JOIN Table1
ON Table1.Col1 = sort.n
I am thinking about this problem two different ways because I can't decide if this is a programming problem or a data architecture problem. Check out the code below incorporating "famous" TV animals. Let's say that we are tracking dolphins, horses, bears, dogs and orangutans. We want to return only the horses, bears, and dogs in our query and we want bears to sort ahead of horses to sort ahead of dogs. I have a personal preference to look at this as an architecture problem, but can wrap my head around looking at it as a programming problem. Let me know if you have questions.
CREATE TABLE #AnimalType (
AnimalTypeId INT NOT NULL PRIMARY KEY
, AnimalType VARCHAR(50) NOT NULL
, SortOrder INT NOT NULL)
INSERT INTO #AnimalType VALUES (1,'Dolphin',5)
INSERT INTO #AnimalType VALUES (2,'Horse',2)
INSERT INTO #AnimalType VALUES (3,'Bear',1)
INSERT INTO #AnimalType VALUES (4,'Dog',4)
INSERT INTO #AnimalType VALUES (5,'Orangutan',3)
CREATE TABLE #Actor (
ActorId INT NOT NULL PRIMARY KEY
, ActorName VARCHAR(50) NOT NULL
, AnimalTypeId INT NOT NULL)
INSERT INTO #Actor VALUES (1,'Benji',4)
INSERT INTO #Actor VALUES (2,'Lassie',4)
INSERT INTO #Actor VALUES (3,'Rin Tin Tin',4)
INSERT INTO #Actor VALUES (4,'Gentle Ben',3)
INSERT INTO #Actor VALUES (5,'Trigger',2)
INSERT INTO #Actor VALUES (6,'Flipper',1)
INSERT INTO #Actor VALUES (7,'CJ',5)
INSERT INTO #Actor VALUES (8,'Mr. Ed',2)
INSERT INTO #Actor VALUES (9,'Tiger',4)
/* If you believe this is a programming problem then this code works */
SELECT *
FROM #Actor a
WHERE a.AnimalTypeId IN (2,3,4)
ORDER BY case when a.AnimalTypeId = 3 then 1
when a.AnimalTypeId = 2 then 2
when a.AnimalTypeId = 4 then 3 end
/* If you believe that this is a data architecture problem then this code works */
SELECT *
FROM #Actor a
JOIN #AnimalType at ON a.AnimalTypeId = at.AnimalTypeId
WHERE a.AnimalTypeId IN (2,3,4)
ORDER BY at.SortOrder
DROP TABLE #Actor
DROP TABLE #AnimalType
ORDER BY CHARINDEX(','+convert(varchar,status)+',' ,
',rejected,active,submitted,approved,')
Just put a comma before and after a string in which you are finding the substring index or you can say that second parameter.
And first parameter of CHARINDEX is also surrounded by , (comma).