Please start any new threads on our new
site at https://forums.sqlteam.com. We've got lots of great SQL Server
experts to answer whatever question you can come up with.
Author |
Topic |
James0816
Starting Member
9 Posts |
Posted - 2014-02-10 : 08:18:42
|
I hate doing this, but I'm stumped on writing a particular query. It's probably a case of me just over thinking it but I haven't had a breakthrough on it yet in a few days. Time to call in some more minds.I have two tables (TableA and TableB). They share similar columns COL1, COL2 and COL3.Sample Data:TableACOL1-----COL2-----COL3100------OPEN-----01-JAN-2014101------CLOSE----12-JAN-2014102------LOCK-----10-JAN-2014103------CLOSE----12-JAN-2014TableBCOL1-----COL2-----COL3100------OPEN-----01-JAN-2014101------OPEN-----04-JAN-2014101------LOCK-----05-JAN-2014101------CLOSE----12-JAN-2014102------OPEN-----08-JAN-2014102------LOCK-----10-JAN-2014103------OPEN-----11-JAN-2014103------CLOSE----12-JAN-2014Here's where it gets interesting. I want to capture all records from TableA and select records from TableB meetings this criteria:- If there is a LOCK record (regardless of other status')- If there is a CLOSE record BUT no associated LOCK recordOutput should look like this:COL1-----COL2-----COL3100------OPEN-----01-JAN-2014101------LOCK-----05-JAN-2014102------LOCK-----10-JAN-2014103------CLOSE----12-JAN-2014I don't have any issues in pulling data matching the first criteria for the LOCKED records. What I am having difficulites with is also pulling the CLOSED records that do not have an associated LOCK with them.Any coding advice would be greatly appreciated. If you have any further questions or need more info, please let me know.Thanks kindly,J. |
|
visakh16
Very Important crosS Applying yaK Herder
52326 Posts |
Posted - 2014-02-10 : 08:43:01
|
[code];WIth CTEAS(SELECT *FROM TableAUNION ALLSELECT *FROM TableB)SELECT COL1,COL2,COL3FROM (SELECT ROW_NUMBER() OVER (PARTITION BY COL1 ORDER BY CASE COL2 WHEN 'LOCK' THEN 0 WHEN 'CLOSE' THEN 1 ELSE 2 END) AS Seq,*FROM CTE)tWHERE Seq=1[/code]------------------------------------------------------------------------------------------------------SQL Server MVPhttp://visakhm.blogspot.com/https://www.facebook.com/VmBlogs |
|
|
James0816
Starting Member
9 Posts |
Posted - 2014-02-10 : 09:02:19
|
In a word.....HUH? Wow. There was no overthinking that. Would have never came up with that query.In either case, I copied and pasted it, changed to the real values and it didn't like the statement:SQL command not properly ended Line 9 Col 1. |
|
|
ScottPletcher
Aged Yak Warrior
550 Posts |
Posted - 2014-02-10 : 17:04:26
|
I didn't get any errors on that code. But, just in case, here's a different approach that doesn't use CTEs or ROW_NUMBER:CREATE TABLE TableA ( col1 int, col2 varchar(10), col3 date )INSERT INTO TableA VALUES(100, 'OPEN', '01-JAN-2014')INSERT INTO TableA VALUES(101, 'CLOSE', '12-JAN-2014')INSERT INTO TableA VALUES(102, 'LOCK', '10-JAN-2014')INSERT INTO TableA VALUES(103, 'CLOSE', '12-JAN-2014')CREATE TABLE TableB ( col1 int, col2 varchar(10), col3 date )INSERT INTO TableB VALUES(100, 'OPEN', '01-JAN-2014')INSERT INTO TableB VALUES(101, 'OPEN', '04-JAN-2014')INSERT INTO TableB VALUES(101, 'LOCK', '05-JAN-2014')INSERT INTO TableB VALUES(101, 'CLOSE','12-JAN-2014')INSERT INTO TableB VALUES(102, 'OPEN', '08-JAN-2014')INSERT INTO TableB VALUES(102, 'LOCK', '10-JAN-2014')INSERT INTO TableB VALUES(103, 'OPEN', '11-JAN-2014')INSERT INTO TableB VALUES(103, 'CLOSE', '12-JAN-2014')GOSELECT COL1, CASE WHEN Lock_Date IS NOT NULL THEN 'LOCK' WHEN Close_Date IS NOT NULL THEN 'CLOSE' ELSE 'OPEN' END AS COL2, COALESCE(Lock_Date, Close_Date, Other_Date) AS COL3FROM ( SELECT COALESCE(a.COL1, b.COL1) AS COL1, MAX(CASE WHEN a.Lock_Date > b.Lock_Date THEN a.Lock_Date ELSE b.Lock_Date END) AS Lock_Date, MAX(CASE WHEN a.Close_Date > b.Close_Date THEN a.Close_Date ELSE b.Close_Date END) AS Close_Date, MAX(CASE WHEN a.Other_Date > b.Other_Date THEN a.Other_Date ELSE b.Other_Date END) AS Other_Date FROM ( SELECT COL1, MAX(CASE col2 WHEN 'LOCK' THEN COL3 END) AS Lock_Date, MAX(CASE col2 WHEN 'CLOSE' THEN COL3 END) AS Close_Date, MAX(COL3) AS Other_Date FROM TableA GROUP BY COL1 ) AS a FULL OUTER JOIN ( SELECT COL1, MAX(CASE col2 WHEN 'LOCK' THEN COL3 END) AS Lock_Date, MAX(CASE col2 WHEN 'CLOSE' THEN COL3 END) AS Close_Date, MAX(COL3) AS Other_Date FROM TableB GROUP BY COL1 ) AS b ON b.COl1 = a.COL1 GROUP BY COALESCE(a.COL1, b.COL1)) AS derivedORDER BY COL1 |
|
|
visakh16
Very Important crosS Applying yaK Herder
52326 Posts |
Posted - 2014-02-11 : 00:47:15
|
quote: Originally posted by James0816 In a word.....HUH? Wow. There was no overthinking that. Would have never came up with that query.In either case, I copied and pasted it, changed to the real values and it didn't like the statement:SQL command not properly ended Line 9 Col 1.
ARe you really using SQL server?I tested and it works for me.------------------------------------------------------------------------------------------------------SQL Server MVPhttp://visakhm.blogspot.com/https://www.facebook.com/VmBlogs |
|
|
James0816
Starting Member
9 Posts |
Posted - 2014-02-11 : 10:53:48
|
I'm using SQL Developer. Copy and pasted your code, modified for actual data values.WIth CTEAS(SELECT * FROM TableA UNION ALLSELECT * FROM TableB)SELECT col1,col2,col3FROM (SELECT ROW_NUMBER() OVER (PARTITION BY col1 ORDER BY CASE col2 WHEN 'LOCK' THEN 0 WHEN 'CLOSE' THEN 1 ELSE 2 END) AS Seq,*FROM CTE)tWHERE Seq=1;Error at Line: 7 Column: 1 |
|
|
James0816
Starting Member
9 Posts |
Posted - 2014-02-11 : 14:22:29
|
Let's just back up a bit here if we can. Like I said, I may be over thinking things and might be making it more complicated than it needs to be. I'm going to steer this in a different direction which is probably where I should have started to begin with.TableA (Master Table) - Contains one record for an event. Status of this record will change depending on what is occuring to it. (I.e. OPEN, LOCK, CLOSE).TableB (Audit Table) - Contains multiple records for a single event. Every time the status of the record is changed, a record is written to this table. For instance and normal cycle would have (1) record in the Master table to (3) records in the Audit table. (Normal cycle is OPEN, LOCK, CLOSE). There is an exception. A record can go from OPEN to CLOSE.For this example, I'm only going to focus on CLOSED records. Nothing more, nothing less. So here is my new sample data:TableA (Has 24 Columns)COL1 ---------- COL2 ---------- COL3 --------------- COL4 ------------ COL5 ................ rowstamp100 ------------- CLOSE -------- 01-JAN-2014 ----- FAIL ------------ {some data} ........ 0000001101 ------------- CLOSE -------- 04-JAN-2014 ----- PASS ---------- {some data} ........ 0000002102 ------------- CLOSE -------- 12-JAN-2014 ----- PASS ---------- {some data} ........ 0000003103 ------------- CLOSE -------- 14-JAN-2014 ----- PASS ---------- {some data} ........ 0000004104 ------------- CLOSE -------- 06-JAN-2014 ----- FAIL ------------ {some data} ........ 0000005105 ------------- CLOSE -------- 09-JAN-2014 ----- PASS ---------- {some data} ........ 0000006106 ------------- CLOSE -------- 10-JAN-2014 ----- FAIL ------------ {some data} ........ 0000007107 ------------- CLOSE -------- 12-JAN-2014 ----- FAIL ------------ {some data} ........ 0000008TableB (Has 6 Columns)COL1 ---------- COL2 ---------- COL3 --------------- COL4 ------------ COL5 ------------- rowstamp100 ------------- OPEN ---------- 30-DEC-2013 ----- {some data} -- {some data} ........ 0000001100 ------------- LOCK ---------- 30-DEC-2013 ----- {some data} -- {some data} ........ 0000002100 ------------- CLOSE -------- 01-JAN-2014 ----- {some data} -- {some data} ........ 0000003101 ------------- OPEN --------- 30-DEC-2014 ----- {some data} -- {some data} ........ 0000004101 ------------- LOCK ---------- 02-JAN-2014 ----- {some data} -- {some data} ........ 0000005101 ------------- CLOSE -------- 04-JAN-2014 ----- {some data} -- {some data} ........ 0000006102 ------------- OPEN ---------- 10-JAN-2014 ----- {some data} -- {some data} ........ 0000007102 ------------- CLOSE -------- 12-JAN-2014 ----- {some data} -- {some data} ........ 0000008103 ------------- OPEN ---------- 14-JAN-2014 ----- {some data} -- {some data} ........ 0000009103 ------------- CLOSE -------- 14-JAN-2014 ----- {some data} -- {some data} ........ 0000010104 ------------- OPEN ---------- 04-JAN-2014 ----- {some data} -- {some data} ........ 0000011104 ------------- LOCK ---------- 05-JAN-2014 ----- {some data} -- {some data} ........ 0000012104 ------------- CLOSE -------- 06-JAN-2014 ----- {some data} -- {some data} ........ 0000013105 ------------- OPEN ---------- 07-JAN-2014 ----- {some data} -- {some data} ........ 0000014105 ------------- LOCK ---------- 09-JAN-2014 ----- {some data} -- {some data} ........ 0000015105 ------------- CLOSE -------- 09-JAN-2014 ----- {some data} -- {some data} ........ 0000016106 ------------- OPEN ---------- 09-JAN-2014 ----- {some data} -- {some data} ........ 0000017106 ------------- CLOSE -------- 10-JAN-2014 ----- {some data} -- {some data} ........ 0000018107 ------------- OPEN ---------- 10-JAN-2014 ----- {some data} -- {some data} ........ 0000019107 ------------- LOCK ---------- 11-JAN-2014 ----- {some data} -- {some data} ........ 0000020107 ------------- CLOSE -------- 12-JAN-2014 ----- {some data} -- {some data} ........ 0000021For my output, I want to track all records from TableA that are in CLOSED status. I want to know when those records were LOCKED. The catch being those records that were CLOSED without first being LOCKED. Therefore that CLOSED status would then be the date I'm looking for.Output from above data should look like this:TblA(Col1) .....TblA(Col2) ..... TblB(Col3) ........... TblA(Col4)100 ------------- CLOSE -------- 30-DEC-2013 ----- FAIL ---> Date record was locked101 ------------- CLOSE -------- 02-JAN-2014 ----- PASS --> Date record was locked102 ------------- CLOSE -------- 12-JAN-2014 ----- PASS --> No LOCK date must use CLOSE date103 ------------- CLOSE -------- 14-JAN-2014 ----- PASS --> No LOCK date must use CLOSE date104 ------------- CLOSE -------- 05-JAN-2014 ----- FAIL ----> Date record was locked105 ------------- CLOSE -------- 09-JAN-2014 ----- PASS --> Date record was locked106 ------------- CLOSE -------- 10-JAN-2014 ----- FAIL ----> No LOCK date must use CLOSE date107 ------------- CLOSE -------- 11-JAN-2014 ----- FAIL ----> Date record was lockedI hope this scenario clears the air and makes it more understandable of what I am trying to accomplish.Once again, I greatly appreciate the assist.Thanks kindly |
|
|
|
|
|
|
|