SQL select from the column and show specific output based on values in the column - sql

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

Related

oracle query to get count of added, updated and deleted records based on the date filter

I have a table structure like below
ID OLDID col1 status
1 0 txt1 A - inserted record
2 0 txt1 I - deleted record
3 0 txt1 I - updated record
4 3 txt1 I - updated record
5 4 txt1 I - updated record
6 5 txt1 I - deleted record
7 0 txtx I - updated record
8 7 txt1 A - updated record
I wanted to count the inserted, updated and deleted record in this table, please help me with the oracle query to fetch the count of the records, below are the logic
The logic for new record is ID is new ID and old id is 0 and status is A.
The updated record's status is I, the id of this record will be inserted into the new record's old id column.
the deleted record status with I with old id 0, and the second condition is status is I and ID will not be in OLD id column.
I have tried my best to explain the case, please let me know if any more details are needed. help me with the oracle query.
below query seems to be working, but if no deleted record then I wanted to have 0 for it but in the below query only returns records which have >0 counts, can any expert optimize it, please
SELECT sub.status, COUNT(*)
FROM (SELECT CASE
WHEN yt.oldid = 0 AND yt.status = 'A' THEN 'Insert'
WHEN yt.status = 'I' and QID not in (select oldid from FROM your_table where TO_CHAR (record_date,'MM/YYYY')='04/2020' ) THEN 'Delete'
ELSE 'Update' END AS status
FROM your_table yt where TO_CHAR (record_date,'MM/YYYY')='04/2020')
GROUP BY sub.status;
Neep experts help here, please.
You can use CASE..WHEN and self LEFT JOIN as follows:
SELECT T.*,
CASE WHEN T.OLDID = 0 AND T.STATUS = 'A' THEN 'Insert'
WHEN T.STATUS = 'I' AND T1.ID IS NOT NULL THEN 'Update'
WHEN T.STATUS = 'I' AND T.OLDID = 0 AND T1.ID IS NULL THEN 'Delete'
END AS RECORD_OP
FROM YOUR_TABLE T
LEFT JOIN YOUR_TABLE T1 ON T.ID = T1.OLDID

How to add new column to table with the value corresponding to the same table?

There is a status column in my table with int values. How can I assign a value to the int or do I have to create a new column in the table?
I have tried to ALTER table but what is the best method?
select status from table1;
If I run the above query we get -
id status
1 1
2 2
3 1
4 5
I want to get output -
id status
1 Accepted
2 Completed
3 Accepted
4 Declined
USE case expression, postgres
select status,
case
when status=1 then 'Accepted'
when status=2 then 'Completed'
when status=3 then 'Accepted'
when sttaus=4 then 'Declined'
end mystatus
from table1;
You can use case, refer to this SO Question
PostgreSQL CASE ... END with multiple conditions. The query will look something like this:
SELECT
id,
CASE
WHEN (status = 1) THEN 'Accepted'
WHEN status=2 then 'Completed'
WHEN status=3 then 'Accepted'
WHEN sttaus=4 then 'Declined'
END AS status
FROM table1 ;
The correct case expression would be:
select id,
(case status
when 1 then 'Accepted'
when 2 then 'Completed'
when 5 then 'Declined'
end) as status
from table1;
You can also do this with a join to a derived table:
select t1.id, v.status
from table1 t1 left join
(value (1, 'Accepted'), (2, 'Completed'), (5, 'Declined')
) v(status_int, status)
on t1.status = v.status_int;
I mention this because you should probably have a reference table for the status values. In this case, the reference table is created on the fly in the query. But it should probably be a real table in the database.

Get table rows by multiple/end column value status

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.

How to group and get count of rows based on value of one column in sql server

I have a table of requests with columns RequestType,status .Status column values can be in-progress,complated etc.
I would like to get the list like
RequestType In-Progress Completed Total
Type1 10 5 15
Type2 10 10 20
I tried with group by using the 2 columns( RequestType,status) ,but it does not give me the exact result.
Please help me with the sql query.
Thanks in advance
Subin
One way to do it is using conditional aggrigation:
SELECT RequestType,
SUM(CASE WHEN Status = 'In-Progress' THEN 1 ELSE 0 END) As 'In-Progress',
SUM(CASE WHEN Status = 'Completed' THEN 1 ELSE 0 END) As 'Completed',
COUNT(Status) As 'Total'
FROM TableName
WHERE Status IN('In-Progress', 'Completed')
GROUP BY RequestType
Use PIVOT
select *, [In-Progress]+[Completed] total
from TableName
pivot ( count(status) for status in ([In-Progress], [Completed])) as p

Counting groupwise category in SQL

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