SQL Server order by case - sql-server

I want to create a fourth column with this query:
select * from (select ID, column0, column1, column2, column3 = Case when
column2 = '' then column1 else column2 end, row_number() over(partition by
column0 order by [column3]) as column4 from myTable) ti
But this error appears:
Invalid column name 'column3'.
I want this result: (red marked column):

you need to use order by from outside of subquery as below:
Select *, row_number() over(partition by
column3 order by [Id]) as column4
from (select ID, column0, column1, column2, column3 = Case when
column2 = '' then column1 else column2 end
from myTable) ti
For your 4th column in image you need to partition by column3 order by id. If you do Partition by column0 then you will get all 1's

This way it will work:
select *, row_number() over(partition by
column0 order by [column3]) as column4 from
(select ID, column0, column1, column2, column3 = Case when
column2 = '' then column1 else column2 end from myTable) ti

Related

How can I find Value for Max from a GROUP BY

I want to group my data by Date and then find "Value" for MAX("SeqNumber"). How can I do this in an aggregate query.
I tried the below, but it gives and error.
Column 'MyTable.SeqNumber' is invalid in the select list because it is
not contained in either an aggregate function or the GROUP BY clause.
Msg 8120, Level 16, State 1, Line 22 Column 'MyTable.Value' is invalid
in the select list because it is not contained in either an aggregate
function or the GROUP BY clause.
Columns:
Date: date
Time: time
Value: float
Code: varchar <<Added in EDIT
SeqNumber: int
Edited query:
SELECT MAX(case [Code] when 'GOLD' then [Value] end) AS BestGold,
MAX(case [Code] when 'SILVER' then [Value] end) as BestSilver
(CASE WHEN [SeqNumber]=MAX([SeqNumber]) THEN [Value] END) AS HIGHEST << Problem
FROM [MyTable]
GROUP BY [Date]
you can achieve this by using using group by and sub query -
select t1.*
from [MyTable] t1 join
( SELECT
MAX([SeqNumber]) as MX_SeqNumber -- you can add your additional columns here
FROM [MyTable]
GROUP BY [Date] ) as t2
on t1.[SeqNumber] = t2.MX_SeqNumber
WITH CTE AS (
SELECT *,
ROW_NUMBER() OVER (PARTITION BY [Date] ORDER BY Sequence DESC) AS RN
FROM YourTable)
SELECT [Value] AS Highest
FROM CTE
WHERE RN = 1;

SSMS / TSQL - Insert multiple records for every record found in query

I want to insert multiple records (two to be specific) with a unique ID for Column 1 (in both records created) for every record that matches a specific query criteria . The rest of the values for the insert should be pulled from the respective columns on the query. In the first insert Column2 will be the original value from Column1, and on the second insert Column2 will be the original value from Column2.
Ideally, what I'm after is:
FIND RECORDS THAT MEETS CRITERIA
FOR EACH RECORD
GENERATE GUID
INSERT TWO NEW RECORDS WITH GUID AS COLUMN1, AND REMAINING COULMNS FROM
CURRENT RECORD FOUND
RECORDS
123 abc 3 4 5
456 def 6 7 8
RECORD 1
123 abc 3 4 5
NEW RECORDS AFTER INSERTS
UID1 123 3 4 5
UID1 abc 3 4 5
ROW 2
456 def 6 7 8
NEW RECORDS AFTER INSERTS
UID2 456 6 7 8
UID2 def 6 7 8
The below INSERT SELECT FROM handles exactly what I want to do but only for a single insert per record found.
INSERT INTO table1
(
Column1,
Column2,
Column3
Column4
Column5
)
SELECT
NEWID(), -- unique ID
Column2, -- or Column1 based on which insert we are doing
Column3, -- always column 3
Column4, --always column 4
Column5 -- always column 5
FROM
table1
WHERE Column1 IS NOT NULL
AND Column1 != Column4
Is there an easy way to do this via TSQL? I need it to run in bulk, for a potential of thousands of records meeting the query conditions.
WITH xQ(UUID,Column2,Column3,Column4,Column5) AS
(
SELECT
NEWID(),
Column1,
Column2,
Column3,
Column4,
Column5
FROM
table1
WHERE Column1 IS NOT NULL
AND Column1 != Column4
)
INSERT INTO table1
(
Column1,
Column2,
Column3,
Column4,
Column5
)
SELECT
UUId,
Column1,
Column3,
Column4,
Column5
FROM xQ
UNION
SELECT
UUId,
Column2,
Column3,
Column4,
Column5
FROM xQ
Here's a possibility. First use your query that generates the first set of rows and insert them into a temp table.
Rextester Demo
SELECT
NEWID() AS [uid], -- unique ID
column1,
Column2, -- or Column1 based on which insert we are doing
Column3, -- always column 3
Column4, --always column 4
Column5 -- always column 5
INTO #temp
FROM
table1
WHERE Column1 IS NOT NULL
AND Column1 != Column4
Now using that temp table we can do a UNION with the same table to generate the second set of rows and insert them into table1.
INSERT INTO table1
SELECT
[uid] AS Column1
, CAST(column1 AS NVARCHAR(3)) AS Column2
, column3
, column4
, column5
FROM #temp
UNION ALL
SELECT
[uid] AS Column1
, column2
, column3
, column4
, column5
FROM #temp
ORDER BY Column1
DROP TABLE #temp

Get the column names matching a multiple column search

For an application, I need to show search results based upon multiple columns. Searching in multiple columns is not that hard, but I also want to know which column(s) the search query matches the text.
Imagine following 'Blabla' table:
---------------------------------------------------------------------------------------
| column1 | column2 | column 3 |
---------------------------------------------------------------------------------------
| Animals are beautiful | Some text regarding music | Vague statement about politics |
---------------------------------------------------------------------------------------
| Music is not his thing | Green is a color | Random gibberish about music |
---------------------------------------------------------------------------------------
Searching for the word 'music' would be as simple as:
SELECT * FROM Blabla WHERE column1 LIKE '%music%' OR column2 LIKE '%music%' OR column2 LIKE '%music%';
But is there a way in SQL to show that matching columns would be column2 for row 1 and column1 + column3 for row 2?
You could use a CASE statement:
SELECT CASE WHEN column1 LIKE '%music%' THEN 'Column1' ELSE '' END AS col1match,
CASE WHEN column2 LIKE '%music%' THEN 'Column2' ELSE '' END AS col2match,
CASE WHEN column3 LIKE '%music%' THEN 'Column3' ELSE '' END AS col3match
FROM Blabla
That would be
select
column1,
column2,
column3,
case
when column1 like '%music%' then 'column1'
when column2 like '%music%' then 'column2'
when column3 like '%music%' then 'column3'
else ''
end as [column]
from Blabla where column1 like '%music%' or column2 like '%music%' or column3 like '%music%'
Not sure about how performant this actually is.
Yes, you can use CASE EXPRESSION for indication columns :
SELECT s.* FROM (
SELECT t.*,
CASE WHEN t.column1 LIKE '%music%' THEN 1 ELSE 0 as col_1_ind,
CASE WHEN t.column2 LIKE '%music%' THEN 1 ELSE 0 as col_2_ind,
CASE WHEN t.column3 LIKE '%music%' THEN 1 ELSE 0 as col_3_ind
FROM Blabla t) s
WHERE 1 IN(s.col_1_ind,s.col_2_ind,s.col_3_ind)
try this,
declare #t table(column1 varchar(100), column2 varchar(100),column3 varchar(100))
insert into #t values
('Animals are beautiful','Some text regarding music','Vague statement about politics')
,('Music is not his thing','Green is a color','Random gibberish about music')
;With CTE as
(
select column1,column2,column3,ROW_NUMBER()over(order by (select null))rn from #t
)
select case when column1 LIKE '%music%' then 'column1 in row'+ cast(rn as varchar) end
,case when column2 LIKE '%music%' then 'column2 in row'+ cast(rn as varchar) end
,case when column3 LIKE '%music%' then 'column3 in row'+ cast(rn as varchar)
end
from cte

Msg 512, Level 16 Error

How can I solve the following problem?
Msg 512, Level 16, State 1, Line 1 Subquery returned more than 1 value. This is not permitted when the subquery follows =, !=, <, <= , >, >= or when the subquery is used as an expression. The statement has been terminated.
I try to get the Frequency like:
| Frequency
| 19
| 23
But somehow I can't get more than I value by firing this Query:
SELECT ts.TimeDifference/ ts.EntryAmount as Frequency
FROM
(
SELECT COUNT(*) as EntryAmount,
(
SELECT DATEDIFF(d, t.minimum, t.maximum)
FROM (SELECT max(Date) AS maximum, min(Date) AS minimum FROM Times GROUP BY column1, column2, column3, column4 HAVING COUNT(*) > 1) t
) AS TimeDifference
FROM Times
) ts
Thank you.
Your innermost sub-select is returning more than one result. You are getting the min and max PER combination of columns 1, 2, 3, and 4. Get rid of the sub-select and it'll resolve the issue.
SELECT
DATEDIFF(d, ts.minimum, ts.maximum)/ ts.EntryAmount as Frequency
,ts.column1, ts.column2, ts.column3, ts.column4
FROM
(
SELECT
COUNT(*) as EntryAmount,
max(Date) AS maximum,
min(Date) AS minimum,
column1, column2, column3, column4
FROM Times
GROUP BY column1, column2, column3, column4
HAVING COUNT(*) > 1
) ts
You can use an aggregate function :
SELECT ts.TimeDifference/ ts.EntryAmount as Frequency
FROM
(
SELECT COUNT(*) as EntryAmount,
(
SELECT Max(DATEDIFF(d, t.minimum, t.maximum))
FROM (SELECT max(Date) AS maximum, min(Date) AS minimum FROM Times GROUP BY column1, column2, column3, column4 HAVING COUNT(*) > 1) t
) AS TimeDifference
FROM Times
) ts

Select nth column in database table

I am talking about SQL Server 2008. I have table with three nvarchar columns. I want to select first column at Nth row, second column from Mth row, third column from Kth row where M,N,K are not equal one to another.
How to write such a query? Also is it possible to select random row?
You can use a CTE with a ROW_NUMBER() function to achieve this:
;WITH CTE AS
(
SELECT
Column1, Column2, Column3,
(your list of additional columns - if needed),
RN = ROW_NUMBER() OVER (ORDER BY InsertionDate)
)
SELECT
FirstValue = (SELECT Column1 FROM CTE WHERE RN = N),
SecondValue = (SELECT Column2 FROM CTE WHERE RN = M),
ThirdValue = (SELECT Column3 FROM CTE WHERE RN = K)
You need to replace the N, M, K with actual integer values in this query - or define SQL variables to hold those three values.
declare #i1 int;
declare #i2 int;
declare #i3 int;
SET #i1=2;
SET #i2=4;
SET #i3=1;
;with t1 as
(
select *,row_number() over(order by (select 0)) as rn from t
)
select max(CASE rn WHEN #i1 then N1 else '' end),
max(CASE rn WHEN #i2 then N2 else '' end),
max(CASE rn WHEN #i3 then N3 else '' end)
from t1 where rn in (#i1,#i2,#i3);

Resources