I have data like this in a table:
https://i.stack.imgur.com/JYZjz.png
I want to group first two events (1, 10) as F1, than second two events (1,10) as F2
Running this SQL query:
SELECT
Id, Date, Event,
CASE
WHEN Event = 1 AND LEAD(Event) OVER (ORDER BY ID) = 10
THEN 'F1'
WHEN Event = 10 AND LAG(Event) OVER (ORDER BY ID) = 1
THEN 'F1'
ELSE NULL
END AS Flow
FROM
lxfr.SystemEventsDiary
WHERE
Event IN (1, 10)
I get this result as output:
ID
Date
Event
Flow
4
2022-02-07 00:00:00.000
1
F1
44
2022-02-08 00:00:00.000
10
F1
47
2022-02-09 00:00:00.000
1
F1
72
2022-02-10 00:00:00.000
10
F1
75
2022-02-10 00:00:00.000
1
F1
97
2022-02-11 00:00:00.000
10
F1
100
2022-02-11 00:00:00.000
1
NULL
113
2022-02-28 00:00:00.000
1
F1
217
2022-03-04 00:00:00.000
10
F1
235
2022-03-22 00:00:00.000
10
NULL
241
2022-03-22 00:00:00.000
1
F1
270
2022-03-24 00:00:00.000
10
F1
273
2022-03-24 00:00:00.000
1
F1
308
2022-03-25 00:00:00.000
10
F1
But I need a result like this:
ID
Date
Event
Flow
4
2022-02-07 00:00:00.000
1
F1
44
2022-02-08 00:00:00.000
10
F1
47
2022-02-09 00:00:00.000
1
F2
72
2022-02-10 00:00:00.000
10
F2
75
2022-02-10 00:00:00.000
1
F3
97
2022-02-11 00:00:00.000
10
F3
100
2022-02-11 00:00:00.000
1
NULL
113
2022-02-28 00:00:00.000
1
F4
217
2022-03-04 00:00:00.000
10
F4
235
2022-03-22 00:00:00.000
10
NULL
241
2022-03-22 00:00:00.000
1
F5
270
2022-03-24 00:00:00.000
10
F5
273
2022-03-24 00:00:00.000
1
F6
308
2022-03-25 00:00:00.000
10
F6
I tried with a CTE, but I'm getting errors...
Thanks
This seems to work. I've copied your desired output as my input sample data just to show that my new column matches your Desired one, and also a couple of other renames for keywords:
declare #t table (ID int, DateOf datetime, EventNo int, DesiredFlow varchar(7))
insert into #t(ID,DateOf,EventNo,DesiredFlow) values
(4 ,'2022-02-07T00:00:00.000',1 ,'F1'),
(44 ,'2022-02-08T00:00:00.000',10 ,'F1'),
(47 ,'2022-02-09T00:00:00.000',1 ,'F2'),
(72 ,'2022-02-10T00:00:00.000',10 ,'F2'),
(75 ,'2022-02-10T00:00:00.000',1 ,'F3'),
(97 ,'2022-02-11T00:00:00.000',10 ,'F3'),
(100 ,'2022-02-11T00:00:00.000',1 ,NULL),
(113 ,'2022-02-28T00:00:00.000',1 ,'F4'),
(217 ,'2022-03-04T00:00:00.000',10 ,'F4'),
(235 ,'2022-03-22T00:00:00.000',10 ,NULL),
(241 ,'2022-03-22T00:00:00.000',1 ,'F5'),
(270 ,'2022-03-24T00:00:00.000',10 ,'F5'),
(273 ,'2022-03-24T00:00:00.000',1 ,'F6'),
(308 ,'2022-03-25T00:00:00.000',10 ,'F6')
;With Neighbours as (
select
*,
LEAD(EventNo,1,NULL) OVER (ORDER BY ID) as Successor,
LAG(EventNo,1,NULL) OVER (ORDER BY ID) as Predecessor
from
#t t
), NoStragglers as (
select
*
from
Neighbours
where
(EventNo = 1 and Successor = 10) or
(EventNo = 10 and Predecessor = 1)
), Ordered as (
select
*, ROW_NUMBER() OVER (PARTITION BY EventNo ORDER BY ID) as rn
from NoStragglers
)
select
t.*,'F' + (CONVERT(varchar(10),o.rn)) as ActualFlow
from
#t t
left join
Ordered o
on
t.Id = o.Id
Hopefully you can see how each CTE builds from the previous one (either by inspection or changing the final select to pull one one of the earlier CTEs instead).
Result:
ID DateOf EventNo DesiredFlow ActualFlow
----------- ----------------------- ----------- ----------- -----------
4 2022-02-07 00:00:00.000 1 F1 F1
44 2022-02-08 00:00:00.000 10 F1 F1
47 2022-02-09 00:00:00.000 1 F2 F2
72 2022-02-10 00:00:00.000 10 F2 F2
75 2022-02-10 00:00:00.000 1 F3 F3
97 2022-02-11 00:00:00.000 10 F3 F3
100 2022-02-11 00:00:00.000 1 NULL NULL
113 2022-02-28 00:00:00.000 1 F4 F4
217 2022-03-04 00:00:00.000 10 F4 F4
235 2022-03-22 00:00:00.000 10 NULL NULL
241 2022-03-22 00:00:00.000 1 F5 F5
270 2022-03-24 00:00:00.000 10 F5 F5
273 2022-03-24 00:00:00.000 1 F6 F6
308 2022-03-25 00:00:00.000 10 F6 F6
Which seems to match.
Check this,
create table #temp(id int,dates datetime,Events int)
insert into #temp(id,dates,events) values
(4 ,'2022-02-07 00:00:00.000', 1 )
,(44 ,'2022-02-08 00:00:00.000', 10 )
,(47 ,'2022-02-09 00:00:00.000', 1 )
,(72 ,'2022-02-10 00:00:00.000', 10 )
,(75 ,'2022-02-10 00:00:00.000', 1 )
,(97 ,'2022-02-11 00:00:00.000', 10 )
,(100 ,'2022-02-11 00:00:00.000', 1 )
,(113 ,'2022-02-28 00:00:00.000', 1 )
,(217 ,'2022-03-04 00:00:00.000', 10 )
,(235 ,'2022-03-22 00:00:00.000', 10 )
,(241 ,'2022-03-22 00:00:00.000', 1 )
,(270 ,'2022-03-24 00:00:00.000', 10 )
,(273 ,'2022-03-24 00:00:00.000', 1 )
,(308 ,'2022-03-25 00:00:00.000', 10 )
WITH CTE
AS (SELECT Id,
Dates,
Events,
CASE
WHEN Events = 1
AND LEAD(Events) OVER(
ORDER BY ID) = 10
THEN id
WHEN Events = 10
AND LAG(Events) OVER(
ORDER BY ID) = 1
THEN LAG(id) OVER(
ORDER BY ID)
ELSE NULL
END AS Flow
FROM #temp),
CtE1
AS (SELECT *,
DENSE_RANK() OVER(
ORDER BY flow) rn
FROM CTe
WHERE flow IS NOT NULL
UNION ALL
SELECT *,
NULL
FROM CTE
WHERE flow IS NULL)
SELECT id,
dates,
events,
CASE
WHEN rn IS NOT NULL
THEN concat('F', rn)
ELSE NULL
END Flow
FROM cte1
ORDER BY id;
drop table #temp
You can use cascading subqueries to assign a ROW_NUMBER() based on Flow values that are NOT NULL:
SELECT d.Id,
d.Date,
d.Event,
CASE WHEN b.rn IS NULL THEN NULL
ELSE CONCAT('F', b.rn)
END AS Flow
FROM (SELECT
Id,
Date,
Event,
Flow,
ROW_NUMBER() OVER (PARTITION BY Event ORDER BY Id ASC) as rn
FROM (SELECT
Id,
Date,
Event,
CASE WHEN Event = 1 AND LEAD(Event) OVER (ORDER BY Id) = 10 THEN 1
WHEN Event = 10 AND LAG(Event) OVER (ORDER BY Id) = 1 THEN 1
ELSE 0
END as Flow
FROM SystemEventsDiary WHERE Event IN (1, 10)
) a WHERE Flow = 1) b
RIGHT JOIN SystemEventsDiary d ON b.id = d.Id
ORDER BY d.Id ASC
Result:
Id
Date
Event
Flow
4
2022-02-07 00:00:00.000
1
F1
44
2022-02-08 00:00:00.000
10
F1
47
2022-02-09 00:00:00.000
1
F2
72
2022-02-10 00:00:00.000
10
F2
75
2022-02-10 00:00:00.000
1
F3
97
2022-02-11 00:00:00.000
10
F3
100
2022-02-11 00:00:00.000
1
NULL
113
2022-02-28 00:00:00.000
1
F4
217
2022-03-04 00:00:00.000
10
F4
235
2022-03-22 00:00:00.000
10
NULL
241
2022-03-22 00:00:00.000
1
F5
270
2022-03-24 00:00:00.000
10
F5
273
2022-03-24 00:00:00.000
1
F6
308
2022-03-25 00:00:00.000
10
F6
db<>fiddle here.
I'm trying to achieve sort of solution to the below table, as I need to make one of the rows in column as column
sku title name product_qty ID warehouse_id
-----------------------------------------------------
S001 Title 1 warehouse1 5 23 1
S001 Title 1 warehouse2 95 23 2
S001 Title 1 warehouse3 3 23 3
S002 Title 2 warehouse1 1 24 1
S002 Title 2 warehouse2 91 24 2
S002 Title 2 warehouse3 0 25 3
and what I would like to achieve
sku title name
warehouse 1 warehouse 2 warehouse 3
S001 Title 1 5 95 3
S002 Title 2 1 91 0
Please try this ... solution...You need to pivot the data.
CREATE TABLE Pivots
(
sku VARCHAR(10)
,title VARCHAR(10)
,name VARCHAR(10)
,product_qty INT
,ID INT
,warehouse_id INT
)
GO
INSERT INTO Pivots VALUES
('S001','Title1','warehouse1',5 , 23 , 1),
('S001','Title1','warehouse2',95 , 23 , 2),
('S001','Title1','warehouse3',3 , 23 , 3),
('S002','Title2','warehouse1',1 , 24 , 1),
('S002','Title2','warehouse2',91 , 24 , 2),
('S002','Title2','warehouse3',0 , 25 , 3)
GO
SOLUTION
SELECT sku,title titlename,ISNULL(MAX(x.warehouse1),0) warehouse1
,ISNULL(MAX(x.warehouse2),0) warehouse2 ,ISNULL(MAX(x.warehouse3),0) warehouse3 FROM Pivots p
PIVOT
(
MAX(product_qty) FOR name IN ([warehouse1],[warehouse2],[warehouse3])
)x
GROUP BY sku,title
OUTPUT
sku titlename warehouse1 warehouse2 warehouse3
---------- ---------- ----------- ----------- -----------
S001 Title1 5 95 3
S002 Title2 1 91 0
(2 rows affected)
SOLUTION 2 - USING conditional aggregation
SELECT sku,title titlename
,ISNULL(MAX(CASE WHEN name = 'warehouse1' THEN product_qty END),0) warehouse1
,ISNULL(MAX(CASE WHEN name = 'warehouse2' THEN product_qty END),0) warehouse2
,ISNULL(MAX(CASE WHEN name = 'warehouse3' THEN product_qty END),0) warehouse3
FROM Pivots p
GROUP BY sku,title
OUTPUT
sku titlename warehouse1 warehouse2 warehouse3
---------- ---------- ----------- ----------- -----------
S001 Title1 5 95 3
S002 Title2 1 91 0
(2 rows affected)
I'm having two table which contain data for reviler for employee on shift basis
e.g
Table 1
------
ID NAME RELIVERID
------------
20 ABC 56
----------
21 XYZ 57
----------
22 DEF 58
----------
TABLE 2
---------
ID NAME RELIVERID
-------
56 PQR 20
-----
57 STU 21
-----
58 XYZ 21
----
I want result in third table with following data
Result Table
-------
ID NAME RELIVERID
---
20 ABC 56
-
56 PQR 20
-
21 XYZ 57
-
57 STU 21
-
22 DEF 58
-
58 XYZ 21
-
1 row from first table and alternate row from second table
My suggestion is to use the row_number function, multiply it with a factor for the 1st table and for the second table add 1 so it will be greater than the one in the 1st table and perform an union all. I don't a SQL Server instance to test this, but it should be something like this:
SELECT (ROW_NUMBER() OVER (ORDER BY ID ASC)) * 100 AS OrderID, * FROM Table1
UNION ALL
SELECT (ROW_NUMBER() OVER (ORDER BY ID ASC)) * 100 + 1 AS OrderID, * FROM Table2
ORDER BY OrderID
For example i have a Table1:
ID Specified TIN Value DateCreated
----------------------------------
1 0 tin1 45 2014-12-30
2 1 tin2 34 2013-01-05
3 0 tin3 23 2015-02-20
4 3 tin4 47 2013-06-04
5 3 tin5 12 2012-04-02
And a Table2:
ID Table1ID RegistrationDate
----------------------------------
1 1 2015-10-12
2 2 2015-07-21
3 1 2015-11-26
4 1 2015-12-04
5 2 2015-09-18
I need select all columns from Table1 with first and last RegistrationDate column in Table2. The answer should be
ID Specified TIN Value DateCreated FirstRegDate LastRegDate
---------------------------------------------------------------
1 0 tin1 45 2014-12-30 2015-10-12 2015-12-04
2 1 tin2 34 2013-01-05 2015-07-21 2015-09-18
3 0 tin3 23 2015-02-20 NULL NULL
4 3 tin4 47 2013-06-04 NULL NULL
5 3 tin5 12 2012-04-02 NULL NULL
Hi one possible solution can be something similar to pseudo query below(if you can prepare the tables I will modify to reflect actual query)
SELECT table1.*, inlineTable2.firstRegDate, inlineTable2.lastRegDate
FROM Table1
LEFT JOIN
(
SELECT
Table1ID AS id,
MIN(registrationDate) as firstRegDate,
MAX(regsitrationDate) as lastRegDate
FROM table2
GROUP BY table1ID
) AS inlineTable2
ON table1.id = inlineTable2.id
You can group by all columns in table1, and look up the minumum and maximum registration date for the group:
select ID
, Specified
, ... other columns from table1 ...
, min(RegistrationDate)
, max(RegistrationDate)
from Table1 t1
left join
Table2 t2
on t1.ID = t2.Table1ID
group by
ID
, Specified
, ... other columns from table1 ...
Is the mechanism used in multiple insertion of rows in the table through single query is same as that of inserting single row with a single query.If not what is the exact mechanism?
If you are fetching the data from an existing table, you can use INSERT INTO TABLE3 ( SELECT * FROM TABLE1 UNION SELECT * FROM TABLE2 ....) to fetch and insert the data in a single go.
SQL> SELECT * FROM SCOTT.EMP WHERE JOB = 'ANALYST1';
EMPNO ENAME JOB MGR HIREDATE SAL COMM DEPTNO GENDER
---------- ---------- --------- ---------- --------- ---------- ---------- ---------- --------
8909 LUTHAR ANALYST1 7698 22-JUL-99 1232 788 50 F
8999 AMAN ANALYST1 7698 22-JUL-99 8569 788 50 M
7788 SCOTT ANALYST1 7566 19-APR-87 3000 150 M
7902 2 ANALYST1 7566 03-DEC-81 3000 M
SQL> SELECT * FROM SCOTT.EMP WHERE JOB = 'MANAGER';
EMPNO ENAME JOB MGR HIREDATE SAL COMM DEPTNO GENDER
---------- ---------- --------- ---------- --------- ---------- ---------- ---------- ---------
7566 5 MANAGER 7839 02-APR-81 2975 150 F
7698 10000 MANAGER 7839 01-MAY-81 2850 150 F
7782 CLARK MANAGER 7839 09-JUN-81 2450 150 F
SQL> CREATE TABLE EMP1 AS ( SELECT * FROM SCOTT.EMP WHERE 1=2);
Table created.
SQL> SELECT * FROM EMP1;
no rows selected
SQL> INSERT INTO EMP1 ( SELECT * FROM SCOTT.EMP WHERE JOB = 'ANALYST1'
2 UNION
3 SELECT * FROM SCOTT.EMP WHERE JOB = 'MANAGER');
7 rows created.
SQL> SELECT * FROM EMP1;
EMPNO ENAME JOB MGR HIREDATE SAL COMM DEPTNO GENDER
---------- ---------- --------- ---------- --------- ---------- ---------- ---------- --------
7566 5 MANAGER 7839 02-APR-81 2975 150 F
7698 10000 MANAGER 7839 01-MAY-81 2850 150 F
7782 CLARK MANAGER 7839 09-JUN-81 2450 150 F
7788 SCOTT ANALYST1 7566 19-APR-87 3000 150 M
7902 2 ANALYST1 7566 03-DEC-81 3000 M
8909 LUTHAR ANALYST1 7698 22-JUL-99 1232 788 50 F
8999 AMAN ANALYST1 7698 22-JUL-99 8569 788 50 M
7 rows selected.
You can chain many SQL statements in a single Oracle query by separating each SQL command with a semicolon. For instance:
INSERT INTO table VALUES(1,2); INSERT INTO table VALUES(3,4);