I have this table . .
ID item_ID status
----------------------------
1 1 'available'
2 1 'available'
3 1 'available'
4 1 'reserved'
5 2 'available'
6 2 'available'
7 3 'reserved'
8 3 'reserved'
9 3 'reserved'
I want my SQL query to return this result:
item_ID quantity
------------------
1 3
2 2
3 0
Please help with this. I'm not really good with T-SQL.
You could use aggregation, but first you need to filter only "available" products:
SELECT item_id, COUNT(*) as quantity
FROM table
WHERE status = 'available'
GROUP BY item_id
ORDER BY item_id;
EDIT:
To get 0 you could use:
SELECT s.item_id, COUNT(t.item_ID) AS quantity
FROM (SELECT DISTINCT item_ID FROM table) s
LEFT JOIN table t
ON s.item_ID = t.item_id
AND t.status = 'available'
GROUP BY s.item_id
ORDER BY s.item_id;
one more way is to use Sum with case
select item_id,
sum(Case when status='available'
then 1 else 0 end) as 'quantity
from
table
group by item_id
Rownum Status
1 2
2 1
3 3
4 2
5 3
6 1
The condition is to query records appear before the first record of status=3 which in the above scenario the expected output will be rownum = 1 and 2.
In the case if there is no status=3 then show everything.
I'm not sure from where to start hence currently no findings
If you are using SQL Server 2012+, then you can use window version of SUM with an ORDER BY clause:
SELECT Rownum, Status
FROM (
SELECT Rownum, Status,
SUM(CASE WHEN Status = 3 THEN 1 ELSE 0 END)
OVER
(ORDER BY Rownum) AS s
FROM mytable) t
WHERE t.s = 0
Calculated field s is a running total of Status = 3 occurrences. The query returns all records before the first occurrence of a 3 value.
Demo here
Table A :
PRID PRTRNSID
1 1
1 2
1 3
2 1
2 2
In this table , For PRID 1 there are 3 child records and For PRID 2 there are 2 child records
Table B :
EVENTTRNID PRID PRTRNSID
1 1 1
2 1 2
3 2 1
4 2 2
In this table , all child records for prid 2 is exists while for prid 1,3rd number child record is missing ,so i need output in following way
OutPut :
PRID Status
1 Pending
2 Done
Can anyone help me for check all child ids exists in another table or not ?
Try this
with A as (select 1 PRID, 1 PRTRNSID from dual
union all
select 1, 2 from dual
union all
select 1, 3 from dual
union all
select 2, 1 from dual
union all
select 2, 2 from dual),
B as (select 1 EVENTTRNID, 1 PRID, 1 PRTRNSID from dual
union all
select 2, 1, 2 from dual
union all
select 3, 2, 1 from dual
union all
select 4, 2, 2 from dual)
select A.prid, case when min(case when B.EVENTTRNID is null then 0 else B.EVENTTRNID end) = 0 then 'Pending' else 'Done' end Status
from A left join B on B.PRID = A.PRID and B.PRTRNSID = A.PRTRNSID
group by A.prid
I have table in SQL Server with values for example :
1
2
2
2
1
2
I want to count how many times there is 1 value, so result of query from my example should be 2
I try
count (case status_d when 1 then 1 end) as COUNT_STATUS_1
but the result is 4, not 2
You can achieve this by using a WHERE clause.
SELECT COUNT(*) As Total_Ones
FROM TABLE_NAME
WHERE ColumnName = 1
Or you can use the case statement as well
SELECT COUNT(CASE WHEN ColumnName = 1 THEN 1 ELSE NULL END) As Total_Ones
FROM TABLE_NAME
SELECT COUNT(*)
FROM YourTable
WHERE status_d = 1
I would like to filter duplicate rows on conditions so that the rows with minimum modified and maximum active and unique rid and did are picked. self join? or any better approach that would be performance wise better?
Example:
id rid modified active did
1 1 2010-09-07 11:37:44.850 1 1
2 1 2010-09-07 11:38:44.000 1 1
3 1 2010-09-07 11:39:44.000 1 1
4 1 2010-09-07 11:40:44.000 0 1
5 2 2010-09-07 11:41:44.000 1 1
6 1 2010-09-07 11:42:44.000 1 2
Output expected is
1 1 2010-09-07 11:37:44.850 1 1
5 2 2010-09-07 11:41:44.000 1 1
6 1 2010-09-07 11:42:44.000 1 2
Commenting on the first answer, the suggestion does not work for the below dataset(when active=0 and modified is the minimum for that row)
id rid modified active did
1 1 2010-09-07 11:37:44.850 1 1
2 1 2010-09-07 11:38:44.000 1 1
3 1 2010-09-07 11:39:44.000 1 1
4 1 2010-09-07 11:36:44.000 0 1
5 2 2010-09-07 11:41:44.000 1 1
6 1 2010-09-07 11:42:44.000 1 2
Assuming SQL Server 2005+. Use RANK() instead of ROW_NUMBER() if you want ties returned.
;WITH YourTable as
(
SELECT 1 id,1 rid,cast('2010-09-07 11:37:44.850' as datetime) modified, 1 active,1 did union all
SELECT 2,1,'2010-09-07 11:38:44.000', 1,1 union all
SELECT 3,1,'2010-09-07 11:39:44.000', 1,1 union all
SELECT 4,1,'2010-09-07 11:36:44.000', 0,1 union all
SELECT 5,2,'2010-09-07 11:41:44.000', 1,1 union all
SELECT 6,1,'2010-09-07 11:42:44.000', 1,2
),cte as
(
SELECT id,rid,modified,active, did,
ROW_NUMBER() OVER (PARTITION BY rid,did ORDER BY active DESC, modified ASC ) RN
FROM YourTable
)
SELECT id,rid,modified,active, did
FROM cte
WHERE rn=1
order by id
select id, rid, min(modified), max(active), did from foo group by rid, did order by id;
You can get good performance with a CROSS APPLY if you have a table that has one row for each combination of rid and did:
SELECT
X.*
FROM
ParentTable P
CROSS APPLY (
SELECT TOP 1 *
FROM YourTable T
WHERE P.rid = T.rid AND P.did = T.did
ORDER BY active DESC, modified
) X
Substituting (SELECT DISTINCT rid, did FROM YourTable) for ParentTable would work but will hurt performance.
Also, here is my crazy, single scan magic query which can often outperform other methods:
SELECT
id = Substring(Packed, 6, 4),
rid,
modified = Convert(datetime, Substring(Packed, 2, 4)),
Active = Convert(bit, 1 - Substring(Packed, 1, 1)),
did,
FROM
(
SELECT
rid,
did,
Packed = Min(Convert(binary(1), 1 - active) + Convert(binary(4), modified) + Convert(binary(4), id)
FROM
YourTable
GROUP BY
rid,
did
) X
This method is not recommended because it's not easy to understand, and it's very easy to make mistakes with it. But it's a fun oddity because it can outperform other methods in some cases.