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
Related
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
I am running a stored procedure and getting the following value.
Name ID NewID Qty Rqty Total
Test1 1 5 4 9
Test2 10 1001 3 0 3
Test2 1001 4 2 6
Test3 15 1005 0 0 0
Test3 1005 3 4 7
If you look the Test3, where first id 15 has a new id 1005 But the Qty and Rqty is 0, next line I am getting ID 1005 and Qty, Rqty 3 and 4, total 7and this is correct.
What I am trying to do is when any ID got a new ID and Qty, Rqty both are 0, I need the following output in on row
Test3 15 1005 3 4 7
So, my final results will be -
Name ID NewID Qty Rqty Total
Test1 1 5 4 9
Test2 10 1001 3 0 3
Test2 1001 4 2 6
Test3 15 1005 3 4 7
My stored procedure is -
select Name, ID, NewID, Qty, RQty, SUM(Qty + RQty) as Total
from table1
Group By Name, ID, NewID, Qty, RQty
Order by Name
Could anyone help to solve this issue please.
Thanks
You will need to generate a psuedo "grouping" ID and NewID based on your conditions, group on those fields and select the MIN and MAX of the original ID and NewID along with aggregates of your other values. e.g.
CREATE TABLE dbo.Tests
(
Name varchar(10),
ID int,
[NewID] int NULL,
Qty int,
Rqty int
);
INSERT dbo.Tests (Name,ID,[NewID],Qty,Rqty)
--VALUES ('Test1',1,NULL,5,4)
-- ,('Test2',10,1001,3,0)
-- ,('Test2',1001,NULL,4,2)
-- ,('Test3',15,1005,0,0)
-- ,('Test3',1005,NULL,3,4);
VALUES ('test1',1,101,0,0)
,('test1',101,NULL,2,4)
,('test2',2,102,0,0)
,('test2',102,NULL,4,5)
,('test3',3,103,0,0)
,('test3',103,NULL,3,3)
,('test4',4,104,0,0)
,('test4',104,NULL,1,3)
,('test5',5,105,0,0)
,('test5',105,NULL,3,6);
SELECT t.Name,
min(t.ID) AS ID,
max(t.[NewID]) AS [NewID],
sum(t.Qty) AS Qty,
sum(t.Rqty) AS Rqty,
sum(t.Qty)+sum(t.Rqty) AS Total
FROM dbo.Tests AS t
CROSS APPLY (VALUES(CASE WHEN Qty = 0 AND Rqty = 0 AND t.[NewID] IS NOT NULL THEN [NewID] ELSE ID END,
CASE WHEN Qty = 0 AND Rqty = 0 AND t.[NewID] IS NOT NULL THEN -1 ELSE coalesce([NewID],-1) END)
) x(GroupingID, GroupingNewID)
GROUP BY Name,x.GroupingID,x.GroupingNewID
ORDER BY Name,max(t.ID);
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;
I got stuck something about stored procedures I write a stored that i need to shot three columns of products count like this
SELECT
Count([TPDTN].[ProductName]) as 'Product Count',
[TPDTN].[CategoryID]
FROM
[TPDTN]
LEFT JOIN
[TPDCN] ON [TPDTN].[CategoryID] = [TPDCN].[libDocumentID]
GROUP BY
[TPDTN].[CategoryID], [TPDCN].[libDocumentID]
It shows results like this:
Product Count CategoryID
---------------------------
2 1
9 2
2 3
2 4
1 5
But I don't know how make it show
Product Count CategoryID libDocumentID
-----------------------------------------------
2 1 123456789
9 2 123456789
2 3 123456789
2 4 123456789
1 5 123456789
Producer ID (LibdocumentID) is from other table but when I SELECT [TPDCN].[libDocumentID] the value is NULL
Product Count CategoryID libDocumentID
------------------------------------------------
2 1 NULL
9 2 NULL
2 3 NULL
2 4 NULL
1 5 NULL
How can I solve it? Thank you
Just add it to the select, and if you don't need the NULL you need an INNER JOIN:
SELECT Count([TPDTN].[ProductName]) as 'Product Count',[TPDTN].[CategoryID], [TPDCN].[libDocumentID]
FROM [TPDTN]
inner join [TPDCN]
ON [TPDTN].[CategoryID] = [TPDCN].[libDocumentID]
GROUP BY [TPDTN].[CategoryID],[TPDCN].[libDocumentID]
Let's say there is a result set...I need to print it out like so:
ID Count
1 5
1 5
1 5
1 5
1 5
2 2
2 2
3 1
Thanks in advance.
Do you mean that your query:
SELECT ID, COUNT(*) AS "Count"
FROM tableX
GROUP BY ID ;
produces this:
ID Count
1 5
2 2
3 1
but you want this?:
ID Count
1 5
1 5
1 5
1 5
1 5
2 2
2 2
3 1
Then, this query will do:
SELECT grp.ID, grp."Count"
FROM
tableX AS t
JOIN
( SELECT ID, COUNT(*) AS "Count"
FROM tableX
GROUP BY ID
) AS grp
ON grp.ID = t.ID ;
It will work in almost all DBMS and in all versions of SQL-Server. For SQL-Server versions 2005 and newer (and also in Oracle and Postgres), the answer with the OVER clause looks more elegant and may be prefered. Test in your version which one is more efficient. I think that in 2012 version, queries with OVER clause are quite efficient.
You can use count() with OVER clause:
select a, count(*) over (partition by a) as [count]
from tableName ;
It's called window function. I recommend you study these.