Reputation: 11
I have a table similar to this:
ID User_Code ProcessID DateCreated Remarks
1 AAA 1 2020-01-01 08:40 N/A
2 AAA 2 2020-01-01 09:34 R123
3 AAA 2 2020-01-01 10:40 SUCCESS
4 AAA 3 2020-01-01 11:00 N/A
5 BBB 1 2020-01-01 11:01 N/A
6 BBB 1 2020-01-01 11:10 N/A
7 BBB 2 2020-01-01 11:20 SUCCESS
8 BBB 3 2020-01-01 11:30 N/A
9 CCC 1 2020-01-01 11:31 N/A
10 CCC 2 2020-01-01 11:40 R001
11 CCC 2 2020-01-01 11:43 R002
What I want to accomplish is to create a result like this
TransDate Remarks UserCode Process1 Process2 Process3
2020-01-01 SUCCESS AAA OK OK OK
2020-01-01 SUCCESS BBB OK OK OK
2020-01-01 R001 CCC OK OK NOK
Where if there is a Record for a Process for the particular UserCode, the column value to be put is OK else if there is no Record, the value would be NOK. Also the Remarks pertains only to Process2, where the value should be the latest Remarks. The problem is it is not outputting the correct result instead it is displaying like this
TransDate Remarks UserCode Process1 Process2 Process3
2020-01-01 AAA OK OK OK
2020-01-01 SUCCESS BBB OK OK OK
2020-01-01 R001 CCC OK OK NOK
See below created SQL:
SELECT UserCode , DATE(DateCreated) AS TransDate,
IF (COUNT(
CASE
WHEN PROCESS = 1
THEN 1
ELSE NULL
END
) > 0, "OK", "NOK" ) AS 'Process1',
IF (COUNT(
CASE
WHEN PROCESS = 2
THEN 1
ELSE NULL
END
) > 0, "OK", "NOK" ) AS 'Process2',
IF (COUNT(
CASE
WHEN PROCESS = 3
THEN 1
ELSE NULL
END
) > 0, "OK", "NOK" )AS 'Process3'
FROM MyTable WHERE UserCode = '######'
GROUP BY DATE(DateCreated)
Sorry got confused, got the wrong data. the record should be
ID User_Code ProcessID DateCreated Remarks
1 AAA 1 2020-01-01 08:40 N/A
2 AAA 2 2020-01-01 09:34 R123
3 AAA 2 2020-01-01 10:40 SUCCESS
4 AAA 3 2020-01-01 11:00 N/A
5 AAA 1 2020-01-02 11:01 N/A
6 AAA 1 2020-01-02 11:10 N/A
7 AAA 2 2020-01-02 11:20 SUCCESS
8 AAA 3 2020-01-02 11:30 N/A
9 AAA 1 2020-01-03 11:31 N/A
10 AAA 2 2020-01-03 11:40 R001
11 AAA 2 2020-01-03 11:43 R002
12 BBB 1 2020-01-03 11:32 N/A
13 BBB 2 2020-01-03 11:38 SUCCESS
14 BBB 3 2020-01-03 11:38 N/A
And the result of the query should be similar to this because the query should be based on a usercode.
TransDate Remarks UserCode Process1 Process2 Process3
2020-01-01 SUCCESS AAA OK OK OK
2020-01-02 SUCCESS AAA OK OK OK
2020-01-03 R002 AAA OK OK NOK
Upvotes: 0
Views: 66
Reputation: 17665
The easy bit is to use conditional aggregation to transform the rows to columns the harder bit joins to a sub query which works out the last id per user_code and plucks the remarks.
select min(date(datecreated)) dt,
max(x.remarks),
t.user_Code,
max(case when processid = 1 then 'ok' else 'nok' end) process1,
max(case when processid = 2 then 'ok' else 'nok' end) process2,
max(case when processid = 3 then 'ok' else 'nok' end) process3
from t
left join
(
select t.user_code,remarks
from t
join
(select t1.user_code ucid, max(t1.id) maxid from t t1 where processid = 2 group by t1.user_Code) s
on s.ucid = t.user_code and s.maxid = t.id
) x on x.user_code = t.user_code
group by t.user_code;
note I have assumed that the remarks in your desired output is incorrect given that the latest remark for user_Code ccc is r002
Upvotes: 1
Reputation: 42834
SELECT DISTINCT
MAX(DATE(DateCreated)) OVER (PARTITION BY User_Code) TransDate,
FIRST_VALUE(CASE ProcessID WHEN 2 THEN Remarks END) OVER (PARTITION BY User_Code ORDER BY CASE ProcessID WHEN 2 THEN DateCreated END DESC) Remarks,
User_Code,
CASE WHEN MAX(CASE WHEN ProcessID = 1 THEN Remarks END) OVER (PARTITION BY User_Code) IS NULL THEN 'NOK' ELSE 'OK' END Process1,
CASE WHEN MAX(CASE WHEN ProcessID = 2 THEN Remarks END) OVER (PARTITION BY User_Code) IS NULL THEN 'NOK' ELSE 'OK' END Process2,
CASE WHEN MAX(CASE WHEN ProcessID = 3 THEN Remarks END) OVER (PARTITION BY User_Code) IS NULL THEN 'NOK' ELSE 'OK' END Process3
FROM test;
TransDate Remarks User_Code Process1 Process2 Process3
2020-01-01 SUCCESS AAA OK OK OK
2020-01-01 SUCCESS BBB OK OK OK
2020-01-01 R002 CCC OK OK NOK
Upvotes: 0