I have a SQL that I've not been able to return the order correctly. Below is example of the rows and the order I want them to appear in. I tried ORDER BY WITH CONDITIONAL CASE AND ROW_NUMBER OVER PARTION without success. I want ColA to be the primary sort and ColB secondary only when ColC has a length < 3 otherwise ColB is primary and ColA is secondary
ColA ColB ColC
5 750 15
5 750 15
3 984 13
3 984 13
5 1021 15
5 1021 15
4 1602 14
4 1602 14
4 1823 14
4 1823 14
6 4099 16
6 4099 16
11 4099 240990
0 10880 10
0 10880 10
3 10881 13
3 10881 13
2 11053 12
8 11053 211053
6 10891 16
6 10891 16
2 11034 12
10 11034 211034
ColA ColB ColC
0 10880 10
0 10880 10
2 11034 12
10 11034 211034
2 11053 12
8 11053 211053
3 984 13
3 984 13
3 10881 13
3 10881 13
4 1602 14
4 1602 14
4 1823 14
4 1823 14
5 750 15
5 750 15
5 1021 15
5 1021 15
6 4099 16
6 4099 16
11 4099 240990
6 10891 16
6 10891 16
order by case when len(ColC) < 3 then ColA else ColB end,
case when len(ColC) < 3 then ColB else ColA end
SQL Fiddle Example
Related
I have data as below :
Month and then corresponding units sold for 3 different item type
Month Sale1 Sale2 Sale3
1 20
2 12
3 50
1 2
2 17
3 56
1 11
2 35
3 9
I want data to be in below format:
Month Sale1 Sale2 Sale3
1 20 2 11
2 12 17 35
3 50 56 9
Maybe SUM is better then MAX if there can be items from one type across different months:
SELECT [Month]
,SUM(Sale1) AS Sale1
,SUM(Sale2) AS Sale2
,SUM(Sale3) AS Sale3
FROM [table]
GROUP BY [Month]
SELECT a.*,
SUM(s.amount) over(ORDER BY s.month rows unbounded preceding) AS a ,
SUM(s.amount) over(PARTITION BY s.month ORDER BY s.month rows unbounded preceding) AS b,
SUM(s.amount) over(PARTITION BY s.month ) AS c_1,
SUM(s.amount) over(PARTITION BY s.month ORDER BY s.month rows BETWEEN unbounded preceding AND unbounded following) AS c,
SUM(s.amount) over(PARTITION BY s.month ORDER BY s.month rows BETWEEN 1 preceding AND unbounded following) AS d,
SUM(s.amount) over(PARTITION BY s.month ORDER BY s.month rows BETWEEN 1 preceding AND 1 following) AS e,
SUM(s.amount) over(PARTITION BY s.month ORDER BY s.month rows BETWEEN unbounded preceding AND 1 following) AS f,
SUM(s.amount) over(PARTITION BY s.month ORDER BY s.month rows CURRENT ROW) AS g
FROM all_sales s,
(SELECT *
FROM all_sales) a
WHERE s.rowid = a.rowid;
/
--above query give the result shown below what is difference between c_1 and c column.
YEAR MONTH PRD_TYPE_ID EMP_ID AMOUNT A B C_1 C D E F G
1 2006 1 1 21 1.00 1 1 10 10 10 3 3 1
2 2006 1 1 21 2.00 3 3 10 10 10 6 6 2
3 2005 1 2 21 3.00 6 6 10 10 9 9 10 3
4 2005 1 2 22 4.00 10 10 10 10 7 7 10 4
5 2006 2 1 21 5.00 15 5 11 11 11 11 11 5
6 2005 2 1 21 6.00 21 11 11 11 11 11 11 6
7 2005 3 1 21 21 7 7 7 7 7
8 2006 3 2 21 7.00 28 7 7 7 7 7 7 7
9 2005 4 1 21 8.00 36 8 17 17 17 17 17 8
10 2006 4 2 21 9.00 45 17 17 17 17 17 17 9
11 2006 5 2 21 45 10 10 10 10 10
12 2005 5 1 21 10.00 55 10 10 10 10 10 10 10
13 2006 6 1 21 11.00 66 11 23 23 23 23 23 11
14 2005 6 1 21 12.00 78 23 23 23 23 23 23 12
15 2005 7 2 21 13.00 91 13 27 27 27 27 27 13
16 2006 7 1 21 14.00 105 27 27 27 27 27 27 14
17 2005 8 2 21 15.00 120 15 31 31 31 31 31 15
18 2006 8 1 21 16.00 136 31 31 31 31 31 31 16
19 2005 9 2 21 17.00 153 17 35 35 35 35 35 17
20 2006 9 1 21 18.00 171 35 35 35 35 35 35 18
21 2005 10 2 21 19.00 190 19 39 39 39 39 39 19
22 2006 10 1 21 20.00 210 39 39 39 39 39 39 20
23 2006 11 1 21 21.00 231 21 43 43 43 43 43 21
24 2005 11 1 21 22.00 253 43 43 43 43 43 43 22
25 2006 12 2 21 23.00 276 23 47 47 47 47 47 23
26 2005 12 1 21 24.00 300 47 47 47 47 47 47 24
You have the same result because your statements are preaty the same:
SUM(s.amount) over(PARTITION BY s.month ) AS c_1,
SUM(s.amount) over(PARTITION BY s.month ORDER BY s.month rows BETWEEN unbounded preceding AND unbounded following) AS c
The cause of it is condition BETWEEN unbounded preceding AND unbounded following because it covers the entire range of partition.
FROM MSDN:
UNBOUNDED PRECEDING - Specifies that the window starts at the first row of the partition. UNBOUNDED PRECEDING can only be specified as window starting point.
UNBOUNDED FOLLOWING - Specifies that the window ends at the last row of the partition. UNBOUNDED FOLLOWING can only be specified as a window end point. For example RANGE BETWEEN CURRENT ROW AND UNBOUNDED FOLLOWING defines a window that starts with the current row and ends with the last row of the partition.
When together they are equal to PARTITION BY s.month
This is the follow up question of : Prepare a recursive query
I have the table with the two columns namely cola and colb as shown below:
Table : Test
create table Test
(
cola int,
colb int
);
Records I have entered are:
Cola Colb
------------
1 2
1 3
1 4
2 5
2 6
2 3
3 2
3 4
3 7
3 10
10 11
11 12
11 13
11 14
12 15
13 16
14 99
15 88
16 77
Note: Now I want to show the only records who are connected with value I have pass. For example If I pass the value as 1 then it should display me the connected number to it and form connect like a tree.
For the above requirement I have got the script from Dark Knight as shown below which works fine.
;WITH CTE AS
(
SELECT COLA,COLB,','+CAST(COLA AS VARCHAR(MAX))+',' AS CHCK FROM test WHERE COLA=1
UNION ALL
SELECT C1.COLA,C1.COLB,C.CHCK+CAST(C1.cola AS VARCHAR(MAX))+','
FROM CTE C INNER JOIN test C1 ON C.colb = C1.cola
WHERE CHARINDEX(','+CAST(C.colb AS VARCHAR(MAX))+',',C.CHCK)=0
),
OUTERCTE AS
(
SELECT DISTINCT COLA,COLB,ROW_NUMBER() OVER(PARTITION BY Colb ORDER BY Cola) rn FROM CTE --ORDER BY COLA
)
SELECT Cola,Colb FROM OUTERCTE
WHERE rn<=1
ORDER BY CASE WHEN Cola = 1 THEN 1 ELSE 2 END;
Which gives me this:
----------------
Cola Colb
----------------
1 2
1 3
1 4
2 5
2 6
3 7
3 10
10 11
11 12
11 13
11 14
12 15
13 16
16 77
15 88
14 99
Requirement: Now I want to show the levels of records.
Expected Result:
------------------------------
Cola Colb Level
------------------------------
1 2 1
1 3 1
1 4 1
2 5 2
2 6 2
3 7 2
3 10 2
10 11 3
11 12 4
11 13 4
11 14 4
12 15 5
13 16 5
16 77 6
15 88 6
14 99 5
;WITH CTE AS
(
SELECT COLA,COLB
,','+CAST(COLA AS VARCHAR(MAX))+',' AS CHCK
, 1 as lvl FROM #Test WHERE COLA=1
UNION ALL
SELECT C1.COLA,C1.COLB ,C.CHCK+CAST(C1.cola AS VARCHAR(MAX))+','
, c.lvl+1
FROM CTE C INNER JOIN #Test C1 ON C.colb = C1.cola
WHERE CHARINDEX(','+CAST(C.colb AS VARCHAR(MAX))+',',C.CHCK)=0
),
cte2 as (
select * , ROW_NUMBER() over (partition by colb order by lvl)as rn From CTE
)
select cola,colb,lvl from cte2 where rn = 1
With Sql Server 2014:
I have two tables - Events and Locations, that share a time column and I need to merge them into one table order by time. In the Events table there is an Event column that I need to place in all the Locations row following that event (time wise), here is an example:
Events:
time event
------------
09:00 2
09:10 3
10:15 1
10:17 2
10:30 3
Locations:
time X Y
-------------
09:01 1 3
09:02 2 3
09:05 4 1
09:09 6 4
09:10 7 8
09:11 8 8
09:12 9 7
10:17 1 2
10:19 5 4
10:20 4 3
10:25 5 4
10:28 3 5
Merged Table:
time X Y event
--------------------
09:00 0 0 2
09:01 1 3 2 <
09:02 2 3 2 <
09:05 4 1 2 <
09:09 6 4 2 <
09:10 0 0 3
09:10 7 8 3 <
09:11 8 8 3 <
09:12 9 7 3 <
10:15 0 0 1
10:17 0 0 2
10:17 1 2 2 <
10:19 5 4 2 <
10:20 4 3 2 <
10:25 5 4 2 <
10:28 3 5 2 <
10:30 0 0 3
The elements that mark with '<' are the inserted Events.
Any ideas and help on how to perform this task is welcome.
You can use UNION ALL and APPLY:
SQL Fiddle
SELECT
[Time], X = 0, Y = 0, [Event]
FROM [Events]
UNION ALL
SELECT l.*, x.Event
FROM Locations l
CROSS APPLY(
SELECT TOP 1 *
FROM [Events]
WHERE [Time] <= l.[Time]
ORDER BY [Time] DESC
)x
ORDER BY [Time]
Source Data:
TID Pid OpID
1 41 1
1 41 2
1 44 1
1 69 1
1 248 1
1 255 1
1 255 2
4 41 1
4 41 2
4 44 1
4 69 1
4 248 1
4 255 1
4 255 2
6 41 1
6 44 1
6 69 1
6 248 1
6 255 1
6 255 2
15 41 1
15 248 1
15 255 1
15 255 2
16 41 1
16 248 1
16 255 1
16 255 2
output:
Pid OpID Unique TId_count
41 1 2
41 2 2
44 1 2
69 1 2
248 1 2
255 1 2
255 2 2
41 1 1
44 1 1
69 1 1
248 1 1
255 1 1
255 2 1
41 1 2
248 1 2
255 1 2
255 2 2
Rules:
1) At first i need to find what are the available PID and OperationID for each TID
2) later consider PID and OPID as a set(group) and find the possible combination of TID and display distinct TID count
Example:
i) for the PID {41,41,44,69,248,255,255} and OperationId {1,2,1,1,1,1,2} is falling in two tester {1,4} so I need the output TID count is 2.
ii) for the PID {41,44,69,248,255,255} and OperationId {1,1,1,1,1,2} is falling in single tester {6} so i need the output TID count is 1.
iii) Finally, for the PID {41,248,255,255} and OperationId {1,1,1,2} is falling in two tester {15,16} so i need the output TID count is 2.
I cannot imagine any use for this ... but check out this anyway:
select pid, opid, count(*) from
(select tid, pid, opid,
(SELECT ',' + cast(x.pid as nvarchar(10))
FROM #temp x
WHERE x.tid = t.tid
FOR XML PATH ('')) as PidGroup,
(SELECT ',' + cast(x.OpId as nvarchar(10))
FROM #temp x
WHERE x.tid = t.tid
FOR XML PATH ('')) as OpIdGroup
from #temp t) innerselect
group by pid, opid, PidGroup, opidgroup
it produces the output you want ... just replace #temp with your tablename.