sql double multiple column key - sql-server

Its an Sql query.
I want to know duplicate data.
Sample:
Table 1
Col1, col2, col3, col4
1, A, AA, AAA
2, A, BB, AAA
3, A, BB, AAA
4, B, AA, AAA
5, B, AA, BBB
6, B, AA, CCC
7, B, BB, AAA
8, B, CC, AAA
the result should be :
2, A, BB, AAA
3, A, BB, AAA
Or
A, BB, AAA
So I can found where's my doubles.
Thank you.

You could also do it like this:
Test data
DECLARE #T TABLE(Col1 int, col2 VARCHAR(100), col3 VARCHAR(100),
col4 VARCHAR(100))
INSERT INTO #T
VALUES
(1, 'A', 'AA', 'AAA'),
(2, 'A', 'BB', 'AAA'),
(3, 'A', 'BB', 'AAA'),
(4, 'B', 'AA', 'AAA'),
(5, 'B', 'AA', 'BBB'),
(6, 'B', 'AA', 'CCC'),
(7, 'B', 'BB', 'AAA'),
(8, 'B', 'CC', 'AAA')
Query1
;WITH CTE
AS
(
SELECT
COUNT(Col1) OVER(PARTITION BY col2,col3,col4) AS Counts,
T.*
FROM
#T AS T
)
SELECT
*
FROM
CTE
WHERE
Counts>1
Result
2 2 A BB AAA
2 3 A BB AAA
Query2
;WITH CTE
AS
(
SELECT
ROW_NUMBER() OVER(PARTITION BY col2,col3,col4 ORDER BY col1) AS RowNbr,
T.*
FROM
#T AS T
)
SELECT
*
FROM
CTE
WHERE
CTE.RowNbr>1
Result
2 3 A BB AAA

You can group by the columns and check whether there is more than 1 record for each group:
select
col2, col3, col4
from
MyTable
group by
col2, col3, col4
having
count(*) > 1
Demo: http://www.sqlfiddle.com/#!3/5c3a7/2

Related

How to query for all groups containing one required element and at least one optional element in sqlite3

Problem & expected result
Suppose I have the following table t:
id f_id col1
---------- ---------- ----------
1 1 B
2 1 C
3 2 A
4 2 C
5 2 D
6 2 E
7 3 A
8 3 D
9 3 E
10 4 A
11 4 B
12 5 C
13 5 D
I would like to select all distinct f_id such that col1 contains one of the following combinations of values:
A and C
A and D
A and C and D
The expected result would therefore be:
f_id
----------
2
3
Own attempt
Based on a previous question I tried the following query
SELECT f_id
FROM t
WHERE (col1 IN ('A', 'C')) or (col1 in ('A', 'D'))
GROUP BY f_id
HAVING COUNT(distinct col1) >= 2;
This query however also matches with groups which contain C and D, but not A. I do not want this because A is important. The above query results in the following:
f_id
----------
2
3
5
How do I obtain the desired result?
Original script
For convenience, here is the code to generate the original table:
drop table if exists t;
CREATE TABLE t (id INTEGER, f_id INTEGER, col1 VARCHAR(1));
INSERT INTO t (id, f_id, col1) VALUES
(1, 1, 'B'),
(2, 1, 'C'),
(3, 2, 'A'),
(4, 2, 'C'),
(5, 2, 'D'),
(6, 2, 'E'),
(7, 3, 'A'),
(8, 3, 'D'),
(9, 3, 'E'),
(10, 4, 'A'),
(11, 4, 'B'),
(12, 5, 'C'),
(13, 5, 'D')
;
First filter the rows of the table so that only rows containing 'A' or 'C' or 'D' in col1 are returned and group by f_id.
Finally set the conditions in the HAVING clause, so that you get only f_ids that contain at least 1 'A' and any of the other 2:
SELECT f_id
FROM t
WHERE col1 IN ('A', 'C', 'D')
GROUP BY f_id
HAVING SUM(col1 = 'A') > 0
AND COUNT(DISTINCT col1) > 1
If there are no duplicates in col1 for each f_id you may change COUNT(DISTINCT col1) > 1 with COUNT(*) > 1.
Or, with EXISTS:
SELECT t1.f_id
FROM t t1
WHERE t1.col1 = 'A'
AND EXISTS (
SELECT 1
FROM t t2
WHERE t2.f_id = t1.f_id AND t2.col1 IN ('C', 'D')
)
See the demo.
Assuming that the order of the combinations is not important:
select f_id, group_concat(col1, '') agg
from t
GROUP BY f_id
HAVING (agg LIKE '%A%' AND agg LIKE '%C%')
OR (agg LIKE '%A%' AND agg LIKE '%D%');
There might be a better way to compare (with regex for example).

How to select each top 1 value from the table based on catgory_id in SQL Server

How to select top 1 value from the table based on category_id?
I have a table like this. Please help me.
Table 1
ID Name category_id
-------------------
1 A 1
2 B 1
3 c 1
4 d 2
5 e 2
6 f 2
7 g 3
8 h 3
9 i 3
How to get the below mentioned output from table 1?
ID Name category_id
--------------------
1 A 1
4 d 2
7 g 3
CREATE TABLE #Table1
([ID] int, [Name] varchar(1), [catgory_id] int)
;
INSERT INTO #Table1
([ID], [Name], [catgory_id])
VALUES
(1, 'A', 1),
(2, 'B', 1),
(3, 'c', 1),
(4, 'd', 2),
(5, 'e', 2),
(6, 'f', 2),
(7, 'g', 3),
(8, 'h', 3),
(9, 'i', 3)
;
SELECT [ID], [Name], [catgory_id]
FROM (
SELECT *
,ROW_NUMBER() OVER (
PARTITION BY [CATGORY_ID] ORDER BY [ID]
) AS RN
FROM #TABLE1
) A
WHERE RN = 1
output
ID Name catgory_id
1 A 1
4 d 2
7 g 3
SELECT TOP 1 WITH TIES [ID], [Name], [catgory_id]
FROM #Table1
ORDER BY
ROW_NUMBER() OVER (
PARTITION BY [CATGORY_ID] ORDER BY [ID] )

Loop inside a group to filter by comparng two column values

Col0 | Col1 | Col2 | Col3
--------------------
1, 14, Orange, 10
2, 14, Pineapple, 10
3, 14, Pear, 14
4, 19, Apple, 6
5, 19, Banana, 5
In the table above, I want to return a row within each group in Col0 (i.e. 14 and 19) where the value in Col1 = Col3 and when there is no value in Col1 = Col3 within a group then return all rows
The result I expect is shown in the table below:
Col0 | Col1 | Col2 | Col3
--------------------
1, 14, Pear, 14
2, 19, Apple, 6
3, 19, Banana, 5
Thanks in advance!
This works, not elegant though
DECLARE #t TABLE (Col0 INT IDENTITY, Col1 INT, Col2 NVARCHAR(15), Col3 INT)
INSERT INTO #t
(Col1, Col2, Col3)
SELECT 14, 'Orange', 10 UNION ALL
SELECT 14, 'Pineapple', 10 UNION ALL
SELECT 14, 'Pear', 14 UNION ALL
SELECT 19, 'Apple', 6 UNION ALL
SELECT 19, 'Banana', 5
;WITH cteX
AS(
SELECT
T.Col1
, Col2 = MAX(T.Col2)
, Col3 = MAX(T.Col3)
FROM #t T
WHERE
T.Col1 = T.Col3
GROUP BY
T.Col1
)
SELECT
Col0 = ROW_NUMBER()OVER(ORDER BY (SELECT NULL))
, Z.Col1
, Z.Col2
, Z.Col3
FROM
(
SELECT
X.Col1
, X.Col2
, X.Col3
FROM cteX X
UNION
SELECT
T.Col1
, T.Col2
, T.Col3
FROM #t T
WHERE
T.Col1 <> T.Col3
AND Col1 NOT IN (SELECT Y.Col1 FROM cteX Y)
) Z
output
Col0 | Col1 | Col2 | Col3
--------------------
1, 14, Pear, 14
2, 19, Apple, 6
3, 19, Banana, 5

How to find max of one column of all child in SQL

I have a chart like picture , that store it in table with KID , ParentID .
how can i get max MR for all child under parent.
example : for Node C ----> max ( MR(D) , MR(E) , MR(F) )
How can find Max(MR) for all child of node?
DECLARE #a TABLE
(
KID INT PRIMARY KEY,
ParentID INT,
MR INT
)
INSERT INTO #a (KID, ParentID, MR)
VALUES
(1, 0, 3), (2, 1, 1), (3, 1, 3),
(4, 3, 3), (5, 3, 5), (6, 5, 3)
;WITH cte AS
(
SELECT *
FROM #a
WHERE ParentID = 3
UNION ALL
SELECT t2.*
FROM cte t1
JOIN #a t2 ON t1.ParentID = t2.KID
)
SELECT MAX(MR)
FROM cte
OPTION (MAXRECURSION 0)
result -
5
Maybe you can use over clause
SELECT
ParentID,
MAX(MR) OVER(PARTITION BY ParentID)
FROM
Table

How to use GROUP BY to identify row differences

I'm working in SQL Server 2008. I have the following situation. I have a table that has 2 columns which comprise the primary key. (No uniqueness constraint is defined on the key, though.) I know that I have primary key duplicates. Per primary key, I want to identify the distinct values in another column. So, let's say I have the following table:
INSERT INTO some_table (Col1, Col2, COl3) VALUES
('A', '1', 'a'),
('A', '1', 'b'),
('B', '1', 'a'),
('B', '2', 'b'),
('C', '1', 'a'),
('C', '1', 'a'),
('C', '2', 'b')
I want to group by Col1 and Col2, and I want to find all rows where there are more than 1 distinct Col3 values. For example, with the above table, I expect to see:
(A, 1, a), (A, 1, b).
How do I write this SQL query? My SELECT statement needs to include Col1, Col2, and Col3. But, if I do a GROUP BY Col1, Col2, then I can't have Col3 in the SELECT statement.
You can't really have more than one item selected per group in group by, but maybe you need something like this:
select
col1,
col2,
stuff((select ',' + col3 from some_table t2
where t1.col1 = t2.col1 and t1.col2 = t2.col2
FOR XML PATH ('')), 1, 1, '') as items
from
some_table t1
group by
col1,
col2
having count(distinct col3) > 1
This will return the "duplicate" items in comma separated list in the 3rd column.
SQL Fiddle
Here is one way to solve this:
;WITH CTE AS (
Select col1, col2, min(col3) as minvalue, max(col3) as maxvalue
From myTable
Group by col1, col2
Having min(col3) < max(col3)
)
Select *
From myTable t
Inner join cte
On t.col1 = cte.col1
And t.col2 = cte.col2
Where col3 >= minvalue
And col3 <= maxvalue
Note code written directly here, there might be some mistakes.
Try this:
CREATE TABLE #some_table
(
Col1 char(1),
Col2 char(1),
Col3 char(1)
)
INSERT INTO #some_table (Col1, Col2, COl3) VALUES
('A', '1', 'a'),
('A', '1', 'b'),
('B', '1', 'a'),
('B', '2', 'b'),
('C', '1', 'a'),
('C', '1', 'a'),
('C', '2', 'b')
select
stuff((select ',' + '('+Col1 +', '+ Col2 + ', ' + Col3 + ')' from #some_table T_IN
where T.col1 = T_IN.col1 and T.col2 = T_IN.col2 FOR XML PATH ('')), 1, 1, '') as items
from
#some_table T
group by col1, col2
This is one way to get there:
SELECT *
FROM
T T1
WHERE
EXISTS(SELECT * FROM T T2
WHERE
T1.a = T2.a
AND T1.b = T2.b
AND T1.c <> T2.c);
sql fiddle
or in similar variation, that would allow to give the required minimum distinct number:
WHERE
(SELECT COUNT(DISTINCT T2.c)
FROM T T2
WHERE T1.a = T2.a AND T1.b = T2.b) >= 2;
sql fiddle

Resources