I have a table with example data like below:
InquiryId status
-------------------
inquiry1 New
inquiry1 Started
inquiry1 Done
inquiry2 New
inquiry2 Pending
inquiry3 New
inquiry3 Started
inquiry4 New
inquiry4 Cancelled
..and so on
Each inquiry starts with status as New and can reach either of the end status'es (Done, Cancelled..) via the middle status'es (Started, Pending..)
The question is how do find the list of inquiries that started with New but never reached the end status, i.e. what SQL query needs to be written to get the list of uncompleted inquiries.
P.S: Using Sybase Database
You can user the following query:
select distinct InquiryId
from <table_name>
where status not in('Done','Cancelled');
It will return all all the InquiryId which doesn't have the status as Done or Cancelled and is still in intermediate state.
You can use not exists :
select t.*
from table t
where status = 'New' and
not exists (select 1
from table t1
where t1.InquiryId = t.InquiryId and
t1.status in ('Done', 'Cancelled')
);
I would use aggregation:
select inquiryId
from t
group by inquiryId
having sum(case when status = 'New' then 1 else 0 end) > 0 and
sum(case when status in ('Done', 'Cancelled') then 1 else 0 end) = 0;
The conditions in the having clause count the number of rows for each inquiryId that meet the given conditions. The > 0 says that the inquiryId has at least one row. The = 0 says that the inquiryId has more than one row.
Related
I have a table STATUSES which contain columns NAME and ACTIVE_FLAG.The column value of NAME may have new, pending, cancel. I want to generate a new output for the count of each NAME with ACTIVE_FLAG=Y
By thinking to use EXISTS to select records for single NAME,
SELECT COUNT(*) AS PENDING
FROM STATUSES
WHERE EXISTS (select NAME from STATUSES where NAME='Pending' and ACTIVE_FLAG = 'Y')
Anyway if I can join other statuses count in a single SQL?
Seems like count and group by
SELECT
name
, count(*)
FROM statuses
WHERE active_flag = 'Y'
GROUP BY name
You can use something like this as i don't see any need to use EXISTS :
SELECT sum(case when name='Pending' then 1 else 0 end) AS PENDING,
sum(case when name='new' then 1 else 0 end) AS NEW,
sum(case when name='cancel' then 1 else 0 end) AS CANCEL
FROM STATUSES
WHERE ACTIVE_FLAG = 'Y'
SQL HERE
I have a scenario where i need to show specific value in new column if I find any specific value( i.e Open, close,WIP then open) and if status =closed then show closed
Data :
ID SUBID Status
1 5 new
1 6 close
1 7 wip
2 22 closed
output i want to get
ID status
1 open
2 closed
You could think about this backwards, and use the else to catch all 'non-closed' rows.
select distinct
id,
case when status = 'closed' then 'closed' else 'open' end
from
yourTable
Scsimon's answer is 100% the best way to handle this based on your sample data.
Just want to add that if an id can have records with 'closed' and other records too (open, new, wip, etc.), use CASE WHEN EXISTS:
SELECT DISTINCT
ID,
CASE WHEN EXISTS (SELECT 1
FROM YourTable T2
WHERE T.ID = T2.ID
AND Status = 'closed')
THEN 'closed'
ELSE 'open'
END as Status
FROM YourTable T
As I am not expert in writing the SQL queries so want for help.
I have the below given dataset
I need to write a query to get all the workorderid's which have skipped the process and moved to next seq_no , ex:
workorderid = AW1 which has a line "open" for seq_no=30 and went ahead to "complete" for seq_no = 40
The final result set should look like below
Workorderid
-----------
AW1
AW3
One method simply uses conditional aggregation:
select workorderid
from t
group by workorderid
having (max(case when status = 'Open' then seq_no end) <
max(case when status = 'Complete' then seq_no end)
)
That is, is there a 'Complete' after the last 'Open', based on seq_no.
Here is another one using EXISTS:
SELECT t1.workorderid
FROM t t1
WHERE t1.status = 'Open'
AND EXISTS
(SELECT 1
FROM t t2
WHERE t2.workorderid = t1.workorderid
AND t2.seq_no > t1.seq_no
AND t2.status = 'Complete')
I need to extract some data to analyse exceptions/logs, and I'm stuck at a point.
I have a table with a column called CallType, and a status which can be Success or Failure. This table also has a column called SessionId.
I need to do this:
Select all the SessionId's where all the CallType = 'A' are marked as Success, but there is at least one CallType = 'B' having a Failure for that session.
There will be a where clause to filter out some stuff.
I'm thinking something like:
select top 10 *
from Log nolock
where ProviderId=48 -- add more conditions here
group by SessionId
having --? what should go over here?
I would do this with conditional aggregation in the having clause:
select top 10 *
from Log nolock
where ProviderId=48 -- add more conditions here
group by SessionId
having sum(case when CallType = 'A' and Status = 'Failure' then 1 else 0 end) = 0 and
sum(case when CallType = 'B' and Status = 'Failure' then 1 else 0 end) > 0 and
sum(case when CallType = 'A' and Status = 'Success' then 1 else 0 end) > 0;
The having clause checks for three conditions by counting the number of rows that meet each one. If = 0, then no records are allowed. If > 0 then records are required.
That CallType A has no failures.
That CallType B has at least one failure.
That at least one CallType A success exists.
The third condition is ambiguous -- if is not clear if you actually need CallType As to be in the data, based on the question.
SELECT *
FROM Log L WITH(NOLOCK)
WHERE L.CallType='A'
AND L.[Status] = 'Success'
AND L.ProviderId = 48
AND EXISTS (SELECT 1
FROM Log
WHERE L.SessionID = SessionID
AND CallType='B'
AND [Status] = 'Failure')
Having clause can only operate on aggregates within the group so this isn't the correct way to go about it since you are filtering out other rows you want to check against. I'd use EXISTS for this e.g.
edit: corrected the query
SELECT *
FROM Log L WITH(NOLOCK)
WHERE ProviderId = 48
AND CallType = 'A'
AND Status = 'Success'
AND EXISTS(SELECT * FROM Log WHERE L.SessionId = SessionId AND CallType = 'B' AND Status = 'Failure')
You can essentially filter out rows in the EXISTS part of the query using the aliased Log table (aliased L), matching all rows with the same session ID and seeing if any match the filters you required (failed with call type B)
I want to find a category wise count in sql server with multiple criteria
Below is the table
I want to find groupwise, checklistcode wise status count
for instance group CLT having total count for Open status and Closed status
so output should look like this
CLT | Clinker transport | CL07M1 | Mechanical Requirments | 4 | 1
I have tried query which is as follows,
select distinct pd.GroupCode,
pd.GroupName,
pd.CheckListCode,
pd.CheckListName,
OpenTotal =
CASE WHEN pd.Status = 'Open' THEN COUNT(pd.Status)
END,
ClosedTotal =
CASE WHEN pd.Status = 'Closed' THEN COUNT(pd.Status)
END
from PunchListDetails pd
group by pd.GroupCode,
pd.GroupName,
pd.CheckListCode,
pd.CheckListName,
pd.Status;
But results is not according to my needs. This above query is showing following result
This is showing in two different lines but i want it in aggregated form as explained above.
Your approach is correct, but you are (also) grouping by the status, so you'll get a different row for each status - hence you get one row that counts the open statuses and one that counts the closed ones.
Just remove pd.Status from the end of the group by clause and you should be fine:
select distinct pd.GroupCode,pd.GroupName,pd.CheckListCode,pd.CheckListName,
OpenTotal =
CASE WHEN pd.Status = 'Open' THEN COUNT(pd.Status)
END,
ClosedTotal =
CASE WHEN pd.Status = 'Closed' THEN COUNT(pd.Status)
END
from PunchListDetails pd
group by pd.GroupCode,pd.GroupName,pd.CheckListCode,pd.CheckListName
You can try this:
SELECT GroupCode
,GroupName
,CheckListCode
,CheckListName,
,SUM(CASE WHEN Status = 'Open' THEN 1 ELSE 0 END) as OpenTotal
,SUM(CASE WHEN Status = 'Closed' THEN 1 ELSE 0 END) as ClosedTotal
FROM PunchListDetails
GROUP BY GroupCode,GroupName,CheckListCode,CheckListName