how to get the count of data based on status id in sql - sql

i have following table
id statusid
100 1
100 2
100 3
101 1
101 3
i am getting the result like following
id data1 data2 data3
100 1 1 1
101 1 0 1
but i want the result like following
id data1 data2+data3
100 1 2
101 1 1
i am using the following query:
select id, SUM(CASE WHEN statusid=1 THEN 1 ELSE 0 END) AS data1,
SUM(CASE WHEN statusid=2 THEN 1 ELSE 0 END) AS data2,
SUM(CASE WHEN statusid=3 THEN 1 ELSE 0 END) AS data3
from employee
group by id
any help.
thank you.
Sudha.

You can count statuses 2 and 3 together like so:
select id,
sum(case when statusid = 1 then 1 else 0 end) as data1,
sum(case when statusid in (2, 3) then 1 else 0 end) as data2_3
from employee
group by id

You may use PIVOT clause to get the required result.
Use DECODE to map the status so that the 2 and 3 produce the same value
with tab2 as (select
id, decode(status_id,3,2,status_id) status_id2
from tab)
select * from tab2
PIVOT (count(*) "CNT" for status_id2 in
(1 as "DATA_1",
2 as "DATA_2_3")
)
ID DATA_1_CNT DATA_2_3_CNT
---------- ---------- ------------
100 1 2
101 1 1

Related

SQL to find IDs which never had a column value

Below is my data:
ID
request_type
1
3
1
2
1
1
1
4
1
5
2
3
2
2
3
4
3
2
I need a query to fetch IDs that never had a request type of 1 (e.g. 2,3 from the previous table).
With conditional aggregation:
select id
from tablename
group by id
having count(case when request_type = 1 then 1 end) = 0
SELECT DISTINCT `ID`
FROM `my_table`
WHERE `ID` NOT IN (
SELECT DISTINCT `ID`
FROM `my_table`
WHERE `request_type` = 1
)
If 1 is the lowest possible value:
select ID
from tab
group by ID
having min (request_type) > 1
Or more generic:
select ID
from tab
group by ID
having max(case when request_type = 1 then 1 else 0 end) = 0

How to update a column based on values of other columns

I have a tables as below
row_wid id code sub_code item_nbr orc_cnt part_cnt variance reporting_date var_start_date
1 1 ABC PQR 23AB 0 1 1 11-10-2019 NULL
2 1 ABC PQR 23AB 0 1 1 12-10-2019 NULL
3 1 ABC PQR 23AB 1 1 0 13-10-2019 NULL
4 1 ABC PQR 23AB 1 2 1 14-10-2019 NULL
5 1 ABC PQR 23AB 1 3 2 15-10-2019 NULL
I have to update var_start_date column with min(reporting_date) for each combination of id,code,sub_code and item_nbr only till variance field is zero.
Row with variance = 0 should have null var_start_date. and next row after that should have next min(var_start_date.). FYI, variance is calculated as par_cnt-orc_cnt
so my output should look like this -
row_wid id code sub_code item_nbr orc_cnt part_cnt variance reporting_date var_start_date
1 1 ABC PQR 23AB 0 1 1 11-10-2019 11-10-2019
2 1 ABC PQR 23AB 0 1 1 12-10-2019 11-10-2019
3 1 ABC PQR 23AB 1 1 0 13-10-2019 NULL
4 1 ABC PQR 23AB 1 2 1 14-10-2019 14-10-2019
5 1 ABC PQR 23AB 1 3 2 15-10-2019 14-10-2019
I am trying to write a function using below query to divide the data into sets.
SELECT DISTINCT MIN(reporting_date)
OVER (partition by id, code,sub_code,item_nbr ORDER BY row_wid ),
RANK() OVER (partition by id, code,sub_code,item_nbr ORDER BY row_wid)
AS rnk,id, code,sub_code,item_nbr,orc_cnt,part_cnt,variance,row_wid
FROM TABLE T1
.But dont know how to include variance field to split the sets.
I would suggest:
select t.*,
(case when variance <> 0
then min(reporting_date) over (partition by id, code, sub_code, item_nbr, grouping)
end) as new_reporting_date
from (select t.*,
sum(case when variance = 0 then 1 else 0 end) over (partition by id, code, sub_code, item_nbr) as grouping
from t
) t;
Note that this does not use a JOIN. It should be more efficient than an answer that does.
Try as below
SELECT T.*, CASE WHEN T.variance = 0 THEN NULL ELSE MIN(reporting_date) OVER (PARTITION BY T1.RANK ORDER BY T1.RANK) END AS New_var_start_date
FROM mytbl T
LEFT JOIN (
SELECT row_wid, variance, COUNT(CASE variance WHEN 0 THEN 1 END) OVER (ORDER BY row_wid ROWS BETWEEN UNBOUNDED PRECEDING AND 1 PRECEDING) +1 AS [Rank]
FROM mytbl
) T1 ON T.row_wid = T1.row_wid
SQL FIDDLE DEMO

SQL -- Multiple rows, similar value in a row, need to not show specific values

Here is the issue:
Table name = a
1 2 3
123 1 A
123 1 A
123 2 A
332 1 A
332 1 A
321 2 B
321 2 A
321 1 A
So far what I have is this:
select distinct 1,2,3 from a where a.2='1' and a.3='B';
What it returns is each result (except for 321).
I only want to select values column 1 as long as that value is not in a row where there is a 2 in column 2 or a B in column 3. Is this possible?
"not in a row where there is a 2 in column 2 or a B in column 3" can be expressed as
select distinct 1,2,3 from a where a.2!='2' or a.3!='B';
or
select distinct 1,2,3 from a where a.2 <> '2' or a.3 <> 'B';
I would use group by and having:
select col1
from t
group by col1
having sum(case when col2 = 2 then 1 else 0 end) = 0 and
sum(case when col3 = 'B' then 1 else 0 end) = 0;

I need 2 count values from single column to be in same row using Over () clause

I have the following Result from Select statement
UnitId UnitType GroupId
1 1 1
2 1 1
3 1 2
4 2 2
5 2 2
6 2 2
7 2 2
I need the following result for each group Id
GroupId CountBasedOnUnitType1 CountBasedOnUnitType2
1 2 0
2 1 4
Thanks in advance.
Try this
SELECT * FROM
(
SELECT GroupId,
UnitType
FROM Table1
) x
Pivot
(
Count(UnitType)
For UnitType in ([1], [2])
) p
Fiddle Demo
Output
GroupId 1 2
1 2 0
2 1 4
Does in necessarily need to have OVER?
select
GroupID,
sum(case when UnitType = 1 then 1 else 0 end) CountBasedOnUnitType1,
sum(case when UnitType = 2 then 1 else 0 end) CountBasedOnUnitType2
from table
group by GroupID

How can we count sub query use group by without pivot?

I need to create query that has below result.
I add my table for example for better understanding.
QTable:
QID Name
-------
1 x
1 y
2 z
FTable:
QID FID
-------
1 1
1 2
2 3
Inner join with :
FID Type
-------
1 1
1 2
1 3
1 4
2 2
2 3
2 3
3 1
3 3
3 3
I need to result like this:
result:
QID FID-Count Type(1)-count Type(2)-count Type(3)-count Type(4)-count
-----------------------------------------------------------------
1 2 1 2 3 1
2 1 1 0 2 0
Thank u for help.
Ususally you can emulate a pivot with GROUP BY and SUM+CASE:
SELECT
T1.QID,
COUNT(DISTINCT T1.FID) as FIDCOUNT,
SUM(CASE WHEN Type=1 THEN 1 ELSE 0 END) as Type1Cnt,
SUM(CASE WHEN Type=2 THEN 1 ELSE 0 END) as Type2Cnt,
SUM(CASE WHEN Type=3 THEN 1 ELSE 0 END) as Type3Cnt,
SUM(CASE WHEN Type=4 THEN 1 ELSE 0 END) as Type4Cnt
FROM QFTable as T1
JOIN T2 ON
T1.FID=T2.FID
GROUP BY T1.QID
ORDER BY QID
SQLFiddle demo