SQL Server query - select id count() - sql-server

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

Related

How to check values of different rows of a table

I have below sample input table. In real it has lots of records.
Input:
ID
Classification
123
1
123
2
123
3
123
4
657
1
657
3
657
4
For a 'ID', I want it's records should have 'Classification' column contains all the values 1, 2, 3 and 4. If any of these values are not present then that ID's records should be considered as an exception. The output should be as below.
ID
Classification
Flag
123
1
0
123
2
0
123
3
0
123
4
0
657
1
1
657
3
1
657
4
1
Can someone please help me with how can this can be achieved in sql server.
Thanks.
There are a couple of options here, which is more performant is up to you to test, not me (especially when I don't know what indexes you have). One uses conditional aggregation, to check that all the values are there, and the other uses a subquery and counts the DISTINCT values (as I don't know if there could be duplicate classifications):
SELECT *
INTO dbo.YourTable
FROM (VALUES(123,1),
(123,2),
(123,3),
(123,4),
(657,1),
(657,3),
(657,4))V(ID,Classification);
GO
CREATE CLUSTERED INDEX CI_YourIndex ON dbo.YourTable (ID,Classification);
GO
SELECT ID,
Classification,
CASE WHEN COUNT(CASE YT.Classification WHEN 1 THEN 1 END) OVER (PARTITION BY ID) > 0
AND COUNT(CASE YT.Classification WHEN 2 THEN 1 END) OVER (PARTITION BY ID) > 0
AND COUNT(CASE YT.Classification WHEN 3 THEN 1 END) OVER (PARTITION BY ID) > 0
AND COUNT(CASE YT.Classification WHEN 4 THEN 1 END) OVER (PARTITION BY ID) > 0 THEN 1 ELSE 0
END AS Flag
FROM dbo.YourTable YT;
GO
SELECT ID,
Classification,
CASE (SELECT COUNT(DISTINCT sq.Classification)
FROM dbo.YourTable sq
WHERE sq.ID = YT.ID
AND sq.Classification IN (1,2,3,4)) WHEN 4 THEN 1 ELSE 0
END AS Flag
FROM dbo.YourTable YT;
GO
DROP TABLE dbo.YourTable;

How to get category count using group by in sql server?

Hi i am create one query for get category count in which some period of time date. in my database i have 3 table first is category , subcategory , subcategoryfollow. now i want to who user follow sub category then i want to count for category. for ex user A follow 3 sub category for category 1 then user B follow same 3 sub category for category 1 then i want category 1 for count is getting 2 like this want result in the query but don't getting this type result.
Here is my query =>
select count(*) as Count,categroyName from categroy s inner join
(
select SS.categroyId from subcategory ss
inner join
(
select count(*) as count,subcategoryId from subcategoryfollow SSS
WHERE SSS.IsFollowed = 1 and CAST(SSS.InsertDateTime as date) >= CAST('2017-07-21' as date)
AND CAST(SSS.InsertDateTime as date) <= CAST('2017-07-22' as date)
group by SSS.subcategoryId,SSS.UserId
) as tab on tab.subcategoryId = ss.subcategoryId group by SS.subcategoryId
) as res on res.categroyId = s.categroyId where s.IsDeleted = 0
GROUP BY res.categroyId,categroyName
This is my current o/p =>
Count | categroyName
1 playing
1 Reading
This is my exepected o/p =>
Count | categroyName
2 playing
1 Reading
Table categroy data =>
categroyId | Name
1 playing
2 Reading
Table subcategory data =>
subcategoryId | categroyId | Name
1 1 cricket
2 1 football
3 1 wallyball
4 2 bibal
5 2 story
Table subcategoryfollow data =>
Id | UserId | subcategoryId | IsFollowed | InsertDateTime
1 10 1 1 2017-07-21 05:57:07.347
2 10 2 1 2017-07-21 05:56:02.347
3 10 3 1 2017-07-21 05:58:01.347
4 11 1 1 2017-07-21 05:59:08.347
5 11 2 1 2017-07-21 05:60:01.347
6 11 3 1 2017-07-21 05:61:06.347
7 13 4 1 2017-07-21 05:61:06.347
8 13 5 1 2017-07-21 05:61:06.347
this is my query and result. now in my table playing category store 3 sub category like cricket,football,wallyball now 2 user follow this 3 sub category so i want count 2 for the palying category. so please any one know how can do that.
I struggle to understand your question fully. Are you looking for something like below query.
SELECT c.Name, COUNT( DISTINCT UserId ) AS Cnt
FROM subcategory AS sc
INNER JOIN subcategoryfollow AS scf ON sc.subcategoryId = scf.subcategoryId
INNER JOIN categroy AS s ON sc.categroyId = s.categroyId
WHERE scf.IsFollowed = 1 and CAST(scf.InsertDateTime as date) >= CAST('2017-07-21' as date)
AND CAST(scf.InsertDateTime as date) <= CAST('2017-07-22' as date)
AND s.IsDeleted = 0
GROUP BY sc.categroyId, c.Name
According to your sample data and your expected result, try with the following SQL statement:
SELECT ucount, category FROM (
SELECT COUNT(F.userid) AS ucount,C.name AS category
FROM Category AS C
INNER JOIN SubCategory AS S ON C.categoryid = S.categoryid
INNER JOIN SubCategoryFollow AS F ON S.subcategoryid = F.subcategoryid
GROUP BY S.name,C.name) AS UserCount
GROUP BY ucount,category;

SQL Server 2012, Rank() & SUM() Over() Until condition

I'm really confused on how to segment these groups into subgroups. This is an example of 2 orders (out of ~5M)
An order may have 1 or more "grouped items".
The group number = SUM(ItemQuantity).
Groups are ordered by OrderLine
eg. In the below table we see one group of "3" & two groups of "2"
OrderNo OrderLine GroupNo ItemQty
10496 1 3 1 =3
10496 2 3 1 =3
10496 3 3 1 =3
10496 4 2 1 =2(1)
10496 5 2 1 =2(1)
10496 6 2 1 =2(2)
10496 7 2 1 =2(2)
Rank() & Dense_Rank dont solve the issue as there are multiples of the same group, OrderLines are different.
I'll be joining this to another table in the end but what I'd like is a way to differentiate the same groups. Perhaps by adding a "subgroup" field.
OrderNo OrderLine GroupNo ItemQty Subgroup
10496 1 3 1 300
10496 2 3 1 300
10496 3 3 1 300
10496 4 2 1 201
10496 5 2 1 201
10496 6 2 1 202
10496 7 2 1 202
Testing below
CREATE TABLE #temptable(
OrderNo varchar(5),
OrderLine int,
GroupNo int,
ItemQty int);
INSERT INTO #temptable (OrderNo,OrderLine,GroupNo,ItemQty)
VALUES
('10496','1','3','1'),
('10496','2','3','1'),
('10496','3','3','1'),
('10495','1','4','1'),
('10495','2','4','2'),
('10495','3','4','1'),
('10495','4','2','1'),
('10495','5','2','1'),
('10495','6','3','1'),
('10495','7','3','2'),
('10495','8','2','1'),
('10495','9','2','1'),
('10495','10','2','1'),
('10495','11','2','1'),
('10495','12','2','1'),
('10495','13','2','1');
A DO WHILE
SUM(ItemQty)Over(Partition by OrderNo,GroupNo Order by OrderLine) >= GroupNo
may work but it'll need to run for every group in every order.
I then started using XML path to query each line but it's really not going to be efficient.
SELECT distinct t1.OrderNo,t1.GroupNo,
STUFF(( SELECT ',' + QUOTENAME(t2.OrderLine)
FROM #temptable t2
WHERE
t2.OrderNo = t1.OrderNo AND t2.GroupNo = t1.GroupNo
Order by t2.OrderLine Asc
FOR XML PATH(''),TYPE
).value('.', 'NVARCHAR(MAX)') ,1,1,'' )
AS [Rows]
FROM #temptable t1
Order by t1.OrderNo,t1.GroupNo
Taking #Nick.McDermaid s advice about the mod % here's a solution, admittedly it could be improved but for now it'll work out.
With a as (
select OrderNo,OrderLine,GroupNo,ItemQty
,CASE
WHEN SUM(ItemQty)Over
(Partition by OrderNo,GroupNo Order by OrderNo,OrderLine) % GroupNo=1
THEN GroupNo*100
ELSE NULL END as SG
from #temptable )
Select a.OrderNo,a.OrderLine,a.ItemQty,a.GroupNo
,MAX(a.SG2)Over(Partition by a.OrderNo,a.GroupNo Order by a.OrderNo,a.OrderLine ROWS BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW ) as Subgroup
from
(Select OrderNo,OrderLine,GroupNo,ItemQty
,CASE WHEN SG IS NULL THEN NULL ELSE SG+RANK()Over(Partition by OrderNo,SG Order by OrderNo,OrderLine) END as SG2
from a )a
Order by a.OrderNo,a.OrderLine;

Selecting count into multiple columns

I have a table like this
MonthYear JobType JobID
01-2014 FullTime 1
01-2014 PartTime 2
02-2014 FullTime 3
03-2014 FullTime 4
04-2014 PartTime 5
04-2014 PartTime 6
04-2014 FullTime 7
I want to select the count of each job type grouped by MonthYear as follows.
MonthYear FullTime PartTime
01-2014 1 1
02-2014 1 0
03-2014 1 0
04-2014 1 2
Can anyone suggest how to achieve this?
Thanks.
SELECT MonthYear,
SUM(CASE WHEN JobType='FullTime' THEN 1 ELSE 0 END) as FullTime ,
SUM(CASE WHEN JobType='PartTime' THEN 1 ELSE 0 END) as PartTime
FROM t
GROUP BY MonthYear
Pivot solution:
SELECT
[MonthYear],
[FullTime],
[PartTime]
FROM
(values
('01-2014', 'FullTime',1),
('01-2014', 'PartTime',2),
('02-2014', 'FullTime',3),
('03-2014', 'FullTime',4),
('04-2014', 'PartTime',5),
('04-2014', 'PartTime',6),
('04-2014', 'FullTime',7)) x(MonthYear, JobType, JobID)
PIVOT (count(JobType)
for JobType
in([FullTime],[PartTime])
)as p
ORDER BY MonthYear

Sql Server query is not giving proper result

I have table SentNewsletters. This table has following columns.
1. ID
2. Surah_no
3. Aayt
4. Sent_date,
5. Sent_By
I want to
select id
,surah_no
,aayt
,sent_date (MAx)
Sent_by, Surah_no and Aayt have multiple records like Id
ID Surah_no aayt sent_date Sent_By
1 1 1 2013-04-08 19:39:26.127 Test
2 1 1 2013-04-08 20:03:24.920 Test
3 1 1 2013-04-08 19:39:26.127 Test
4 1 1 2013-04-08 20:03:24.920 Test
5 1 1 2013-04-08 20:19:26.033 User3
6 1 1 2013-04-08 20:24:47.890 User3
select Count(*)
,surano
,Aaytno
,MAx(SENT_DATE)
from sentnewsletters
group by SuraNo
,Aaytno
I need Id and Sent_By also
select Count(*)
ID
,surano
,Aaytno
,MAx(SENT_DATE) ,
Sent_by
from sentnewsletters
group by SuraNo
,Aaytno
You could use...
select Count(*) as Count
,surano
,Aaytno
,MAx(SENT_DATE) as SentDate ,
Sent_by
from sentnewsletters
group by SuraNo
,Aaytno
,Sent_by
You can't group on the ID since each record is different, you will essentially have the same result as just querying the table with...
select 1 as Count
,surano
,Aaytno
,SENT_DATE,
Sent_by
from sentnewsletters
The result woudl look like..
Count Surah_no aayt sent_date Sent_By
4 1 1 2013-04-08 20:03:24.920 Test
2 1 1 2013-04-08 20:24:47.890 User3

Resources