SQL Server distinct rows count - sql-server

Say there is the following table in SQL Server :
ID Column1 Column2 Column3
1 1 2 10
1 1 2 20
2 1 2 30
2 1 2 40
3 3 4 50
3 3 4 60
3 3 4 70
I need to select the SUM on Column3 grouped by Column1, Column2 and select the count of rows with DISTINCT "ID". Consider the query :
SELECT SUM(Column3) AS Column3
COUNT(*) AS Count
FROM MyTable
GROUP BY Column1,
Column2
The result will be :
Column3 Count
100 4
110 3
I expect to get :
Column3 Count
100 2
110 1
So the count here will be by DISTINCT "ID" values.
In the first row 2 means there are two different ID values (1 and 2) with the same Column1, Column2
In the second row 1 means there is just one distinct value (that is 3) with the same Column1, Column2.
Can you please advice me the correct way to get the expected result.
Thanks in advance.

Use COUNT(DISTINCT): http://msdn.microsoft.com/en-us/library/ms175997.aspx
SELECT SUM(Column3) AS Column3
COUNT(DISTINCT ID) AS Count
FROM MyTable
GROUP BY Column1,
Column2

Not sure I'm understanding you right, but does this work?:
;WITH cte AS (SELECT ID, column1, column2, SUM(column3) AS column3sum FROM table GROUP BY id, column1, column2)
SELECT SUM(column3sum), COUNT(ID)
FROM cte
GROUP BY column1, column2

Related

SQL Server: How to get the top 'N' max occurrences from each group

I have a below dataset and I am trying to get max occurrences of CID per each OID.
IF OBJECT_ID('TEMPDB..#SS',N'U') IS NOT NULL
DROP TABLE #SS
GO
SELECT * INTO #SS FROM (
SELECT 1 AS OID,501 AS CID
UNION ALL
SELECT 1 AS OID,503 AS CID
UNION ALL
SELECT 1 AS OID,502 AS CID
UNION ALL
SELECT 1 AS OID,501 AS CID
UNION ALL
SELECT 1 AS OID,501 AS CID
UNION ALL
SELECT 2 AS OID,502 AS CID
UNION ALL
SELECT 2 AS OID,502 AS CID
UNION ALL
SELECT 2 AS OID,502 AS CID
UNION ALL
SELECT 2 AS OID,501 AS CID
UNION ALL
SELECT 1 AS OID,503 AS CID
)A
GO
In above sample dataset, I need to get 2 CID per each OID which occurred maximum times. The expected result could be:
OID CID
1 501
1 503
2 501
2 502
This cannot be a duplicate to SQL Select top frequent records because I need this sub-queries and SQL-Server would not accept ORDER BY in sub-query and eventually I need a ranking function to solve my issue. Ranking function was not used in the link provided.
You can do this pretty easily utilizing ROW_NUMBER. Thanks for Tab Alleman for the clarification on your requirements.
select *
from
(
select *
, RowNum = ROW_NUMBER() over (partition by OID order by count(*) desc)
from #SS
group by OID
, CID
) x
where x.RowNum <= 2
order by x.OID
, x.CID

Check if we have matching data for two columns inside a group

I have some data like:
ID Col1 Col2
--- ----- -----
5 10 10 <--- Matching
5 11 10
5 15 10
6 22 22 <--- Matching
6 10 22
6 12 22
And I tried a query like:
SELECT ID FROM #Table
GROUP BY ID HAVING MAX(COL1) = MAX(COL2)
But, this only returns id 6, as max for group 5 Col1 is 15 which does not match with Col2 max value 10 for group 5. Is there any way to get all groups 5 & 6 which has matching data 10 & 22 in Col1 & Col2?
Expected Output:
ID
---
5
6
Just showing the ID of matching group.
It is as smiple as this:
DECLARE #tblQuestion AS Table
(
ID int,
col1 int,
col2 int
)
INSERT INTO #tblQuestion VALUES
(5,10,10),
(5,11,10),
(5,15,10),
(6,22,22),
(6,10,22),
(6,12,22);
select distinct ID from #tblQuestion a
where a.col1 = a.col2
TRY THIS:
SELECT DISTINCT ID
FROM table_name
WHERE (col1 - col2) = 0
Try the below query. Maybe it is your requirement, first get same value rows and then get max value from group:
DECLARE #tblQuestion AS Table
(
ID INT,
Col1 INt,
Col2 INT
)
INSERT INTO #tblQuestion VALUES(5,10,10)
INSERT INTO #tblQuestion VALUES(5,10,21)
INSERT INTO #tblQuestion VALUES(5,27,10)
INSERT INTO #tblQuestion VALUES(6,10,12)
INSERT INTO #tblQuestion VALUES(6,15,15)
INSERT INTO #tblQuestion VALUES(6,25,25)
INSERT INTO #tblQuestion VALUES(6,18,10)
;WITH T AS
(
SELECT
*,
ROW_NUMBER() OVER (Partition BY ID order by Col1 Desc) AS PartNo
FROM #tblQuestion
WHERE Col1=Col2
)
SELECT ID,Col1,Col2 FROM T
WHERE PartNo=1
ORDER BY ID, Col1 DESC
Output:
Try this:
SELECT distinct ID FROM table_name
where COL1 = COL2
In my case I tried a different approach, as I needed to use GROUP BY & HAVING clause due to my original query complexity like:
SELECT DISTINCT ID FROM #Table
GROUP BY ID
HAVING MAX(CASE WHEN Col1 = Col2 THEN 1 ELSE 0 END) = 1
Just wanted to share my solution here, in case anyone is interested.

Sybase + how to compute sequence number for a speicific group

Date column1 column2 column3 column4 column5
01-Jan-17 A AB 10 AB_1 10
02-Jan-17 B AB 20 AB_2 10
03-Jan-17 C AB 30 AB_3 10
04-Jan-17 D AB 20 AB_4 -10
05-Jan-17 E AB 40 AB_5 20
06-Jan-17 X GH 30 GH_1 30
07-Jan-17 V GH 40 GH_2 10
08-Jan-17 A GH 50 GH_3 10
Requirement1 :For all the columns having same value in column2, the column4 should be numbered sequentially
Requirement2:For all the columns having same value in column2, the column5 should be computed as current value of column3 - previous value of column3
Appreciate your help!!
I'm using Adaptive Server Enterprise/15.7/EBF 22234 SMP SP121 /P/x86_64/Enterprise Linux/ase157sp12x/3660/64-bit/FBO/
You can achieve this with multi-step processing as follows (I didn;t test it, but you'll get the idea). Assuming your table is named 't'.
select your_date, column1, column2, column3, id = identity(9) into #t1 from t order by column2, column3 -- this seems to be the ordering you want?
select column2, min(id) as min_id into #t2 from #t1 group by column2
select #t1.* column4 = (#t1.id - #t2.min_id + 1) into #t3 from #t1, #t2 where #t2.column2 = #t1.column2
select ta.*, column5 = case when tb.id is null or tb.column2 <> ta.column2 then ta.column3 else ta.column3 - tb.column3 from #t3 ta, #t1 tb where ta.id *= (tb.id - 1)

SSMS / TSQL - Insert multiple records for every record found in query

I want to insert multiple records (two to be specific) with a unique ID for Column 1 (in both records created) for every record that matches a specific query criteria . The rest of the values for the insert should be pulled from the respective columns on the query. In the first insert Column2 will be the original value from Column1, and on the second insert Column2 will be the original value from Column2.
Ideally, what I'm after is:
FIND RECORDS THAT MEETS CRITERIA
FOR EACH RECORD
GENERATE GUID
INSERT TWO NEW RECORDS WITH GUID AS COLUMN1, AND REMAINING COULMNS FROM
CURRENT RECORD FOUND
RECORDS
123 abc 3 4 5
456 def 6 7 8
RECORD 1
123 abc 3 4 5
NEW RECORDS AFTER INSERTS
UID1 123 3 4 5
UID1 abc 3 4 5
ROW 2
456 def 6 7 8
NEW RECORDS AFTER INSERTS
UID2 456 6 7 8
UID2 def 6 7 8
The below INSERT SELECT FROM handles exactly what I want to do but only for a single insert per record found.
INSERT INTO table1
(
Column1,
Column2,
Column3
Column4
Column5
)
SELECT
NEWID(), -- unique ID
Column2, -- or Column1 based on which insert we are doing
Column3, -- always column 3
Column4, --always column 4
Column5 -- always column 5
FROM
table1
WHERE Column1 IS NOT NULL
AND Column1 != Column4
Is there an easy way to do this via TSQL? I need it to run in bulk, for a potential of thousands of records meeting the query conditions.
WITH xQ(UUID,Column2,Column3,Column4,Column5) AS
(
SELECT
NEWID(),
Column1,
Column2,
Column3,
Column4,
Column5
FROM
table1
WHERE Column1 IS NOT NULL
AND Column1 != Column4
)
INSERT INTO table1
(
Column1,
Column2,
Column3,
Column4,
Column5
)
SELECT
UUId,
Column1,
Column3,
Column4,
Column5
FROM xQ
UNION
SELECT
UUId,
Column2,
Column3,
Column4,
Column5
FROM xQ
Here's a possibility. First use your query that generates the first set of rows and insert them into a temp table.
Rextester Demo
SELECT
NEWID() AS [uid], -- unique ID
column1,
Column2, -- or Column1 based on which insert we are doing
Column3, -- always column 3
Column4, --always column 4
Column5 -- always column 5
INTO #temp
FROM
table1
WHERE Column1 IS NOT NULL
AND Column1 != Column4
Now using that temp table we can do a UNION with the same table to generate the second set of rows and insert them into table1.
INSERT INTO table1
SELECT
[uid] AS Column1
, CAST(column1 AS NVARCHAR(3)) AS Column2
, column3
, column4
, column5
FROM #temp
UNION ALL
SELECT
[uid] AS Column1
, column2
, column3
, column4
, column5
FROM #temp
ORDER BY Column1
DROP TABLE #temp

Removing rows , if they have duplicate

Lets suppose I have a following table in sql server 2008.
Column1 Column2 Column3
1 2 1
1 2 1
5 1 1
3 2 1
3 2 1
4 1 1
The output should be following
Column1 Column2 Column3
5 1 1
4 1 1
If a row has a duplicates present then , the original row and all the duplicate rows are to be deleted.If a row doesnot have any duplicates. Then it is kept. How can i achieve this?
Try like this,
DECLARE #Table TABLE (
Column1 INT
,Column2 INT
,Column3 INT
)
INSERT INTO #Table
(Column1,Column2,Column3)
VALUES
(1,2,1),
(1,2,1),
(5,1,1),
(3,2,1),
(3,2,1),
(4,1,1)
SELECT *
FROM #Table
DELETE t1
FROM #Table t1
INNER JOIN (
SELECT Column1
,Column2
,Column3
FROM #Table t
GROUP BY Column1
,Column2
,Column3
HAVING count(*) > 1
) t2 ON t1.column1 = t2.Column1
AND t1.column2 = t2.column2
AND t1.column3 = t2.column3
SELECT * FROM #Table

Resources