Identify the pattern to get desired output - sql

We have below table contains multiple code against the ID and CounterID. Need an output based on code and id.
Condition: Against the ID and CounterID
case 1 : if there is code CI and CO then no record
case 2 : if there is code CI and CO and CI then last record with code CI
case 3 : if there is code CI then last CI
Thanks
Rahul

You can use the analytical function as follows:
select t.* from
(select t.*, row_number() over (partition by sno order by date desc) as rn,
count(case when code = 'CI' then 1 end) over (partition by sno) as cicount,
count(case when code = 'CO' then 1 end) over (partition by sno) as cocount
from your_table t) t
where ( (cocount = 0)
or not (cicount = 1 and cocount = 1)
or (cocount > cicount ))
and rn = 1

Your logic simplifies to: The last row when it has 'CI'. One method with window functions is:
select t.*
from (select t.*,
row_number() over (partition by id order by date desc) as seqnum
from t
) t
where seqnum = 1 and code = 'CI';
You can also do this without window functions:
select t.*
from t
where code = 'CI' and
date = (select max(t2.date) from t t2 where t2.id = t.id);

Related

Query doesn't work when adding another condition with PARTITION BY

Originally I had the following query:
SELECT T.* FROM
(SELECT *, row_number() OVER
(PARTITION BY manager_id ORDER BY id) AS sn FROM my_table) T
WHERE (sn = 1)
AND ((checkbox IS NULL OR (checkbox = 0)
)
but then I added another boolean column to the db called "not_relevant" and I want to show results where its value is not 1, so I added the following:
SELECT T.* FROM
(SELECT *, row_number() OVER
(PARTITION BY manager_id ORDER BY id) AS sn FROM my_table) T
WHERE (sn = 1)
AND ((checkbox IS NULL) OR (checkbox = 0)
AND (not_relevant != 1)
)
But I get the same results even if not_relevant is 1
Why?

SQL to find records with last 3 same status

I have the following tasks table:
id type submit_time status
I need to run a query that returns only the types which their last 3 tasks finished with status "FAILED".
How can I do this?
Should I use a window function?
Thanks
You can use aggregation and filtering after using row_number() to get the last three rows:
select type
from (select t.*,
row_number() over (partition by type order by submit_time desc) as seqnum
from t
) t
where seqnum <= 3
group by type
having min(status) = max(status) and min(status) = 'FAILED' and
count(*) = 3;
Actually, a slightly simpler method is:
select type
from (select t.*,
row_number() over (partition by type order by submit_time desc) as seqnum
from t
) t
where seqnum <= 3 and status = 'FAILED'
group by type
having count(*) = 3;

Max date and order by status exist at first occurrence if not found next value

I have a table as below
ID,DATE,Status
359,2021-05-01,M
359,2021-05-01,R
359,2021-04-01,M
759,2021-05-01,R
759,2021-04-01,O
123,2021-05-01,M
123,2021-04-01,O
123,2021-03-31,U
and I want the result as below
359,2021-05-01,R
759,2021-05-01,R
123,2021-05-01,M
Date - Max/Latest date
Status:
First preference should be R(Exit if R found)
If R doesn't exist then M
If M doesn't exist then O
If O doesn't exist then U etc.,
Could someone please help me with this?
Thanks in advance
One method is row_number():
select t.*
from (select t.*,
row_number() over (partition by id order by case status when 'R' then 1 when 'M' then 2 when 'O' then 3 when 'U' then 4 else 5 end
) as seqnum
from t
) t
where seqnum = 1;
If you know all the statuses, a shortcut is:
select t.*
from (select t.*,
row_number() over (partition by id order by charindex('RMOU', status)) as seqnum
from t
) t
where seqnum = 1;

Selecting the latest order

I need to select the data of all my customers with the records displayed in the image. But I need to get the most recent record only, for example I need to get the order # E987 for John and E888 for Adam. As you can see from the example, when I do the select statement, I get all the order records.
You don't mention the specific database, so I'll answer with a generic solution.
You can do:
select *
from (
select t.*,
row_number() over(partition by name order by order_date desc) as rn
from t
) x
where rn = 1
You can use analytical function row_number.
Select * from
(Select t.*,
Row_number() over (partition by customer_id order by order_date desc) as rn
From your_table t) t
Where rn = 1
Or you can use not exists as follows:
Select *
From yoir_table t
Where not exists
(Select 1 from your_table tt
Where t.customer_id = tt.custome_id
And tt.order_date > t.order_date)
You can do it with a subquery that finds the last order date.
SELECT t.*
FROM yoir_table t
JOIN (SELECT tt.custome_id,
MAX(tt.order_date) MaxOrderDate
FROM yoir_table tt
GROUP BY tt.custome_id) AS tt
ON t.custome_id = tt.custome_id
AND t.order_date = tt.MaxOrderDate

Split Record into multiple column after Row_number and Partition By

I want to have my result to be displayed in 4 columns.
This is how I did my coding.
SELECT T.MT_CARD_TYP_ID,
ROW_NUMBER() OVER (PARTITION BY T.APP_ID ORDER BY T.DT_CREATE) AS RN
FROM T_CS_FAC_CC T
WHERE app_id = '8F9A97B0CB5349429C44F15830EDC18F';
What should I do the next step? Can someone pro help me out please?
This is how my result look
This is how I want the result look like.
You can try to use condition aggravated function.
SELECT app_id,
MAX(CASE WHEN RN = 1 THEN MT_CARD_TYP_ID END),
MAX(CASE WHEN RN = 3 THEN MT_CARD_TYP_ID END),
MAX(CASE WHEN RN = 2 THEN MT_CARD_TYP_ID END),
MAX(CASE WHEN RN = 4 THEN MT_CARD_TYP_ID END)
FROM (
SELECT T.MT_CARD_TYP_ID, ROW_NUMBER() OVER(PARTITION BY T.APP_ID ORDER BY T.DT_CREATE) AS RN
FROM T_CS_FAC_CC T
where app_id='8F9A97B0CB5349429C44F15830EDC18F'
)t1
GROUP BY app_id