I have two tables tblDoc and tblrev
tblDoc
DocID DocNum
1 Doc-001
2 Doc-002
3 Doc-003
4 Doc-004
5 Doc-005
tblRev
revID DocID ReV
1 2 A
2 2 A
3 1 B
4 3 c
I need to select DocID and revID of the duplicates in tblRev where a duplicate record is known as with the same DocID and Rev.
ex: revID 1,2 is a duplicate
plz help
SELECT revID
FROM TblRev
WHERE Rev IN
(
SELECT ReV
FROM tblRev
GROUP BY Rev, DocId
HAVING COUNT(*) > 1
)
Try the following:
;WITH Duplicates AS
(
SELECT
[DocID]
, [ReV]
, COUNT([revID]) as [Count]
FROM tblRev
GROUP BY
[DocID]
, [ReV]
),
DuplicateRevID AS
(
SELECT
R.[revID]
, R.[DocID]
FROM Duplicates D
INNER JOIN tblRev R ON
D.[DocID] = R.[DocID]
AND D.[ReV] = R.[ReV]
WHERE
D.[Count] > 1
)
SELECT *
FROM DuplicateRevID
Try this
select tr.revID,tr.DocID FROM tblDoc td
Inner Join tblRev tr on td.DocID = tr.DocID
GROUP BY tr.revID,tr.DocID
Having count(td.DocID )> 1
Related
How I can do select a primary key in grouping by clause, and it will return max value from another table which not in group by clause? For example :
Table A :
ID table_b_id Value
1 1 100
2 1 200
3 1 150
4 2 300
5 2 200
6 2 100
7 3 100
8 3 200
Table B
ID Name
1 A
2 B
3 C
Result Expected
B.ID B.Name A.ID
1 A 2
2 B 4
3 C 8
I've try some queries like this :
select b.id, max(b.name), max(a.id) as kd_rec
from table_a a join table_b
on a.table_b_id = b.id
group by b.id
I don't know how to get max value from table a group by b.
If you don't want the Name from tableB, then
Query
;with cte as
(
select rn=row_number() over
(
partition by table_b_id
order by [Value] desc
),*
from tableA
)
select table_b_id as [B.ID],
ID as [A.ID]
from cte
where rn=1;
Fiddle demo
If you want the Name also in the result set, then
Query
;with cte as
(
select rn=row_number() over
(
partition by table_b_id
order by [Value] desc
),*
from tableA
)
select t1.table_b_id as [B.ID],
t2.Name as [B.Name],
t1.ID as [A.ID]
from cte t1
join tableB t2
on t1.table_b_id=t2.ID
where t1.rn=1;
Fiddle demo
I want to group the key with count greater than 3, and the query will return the rest of the records also. I don't want to use Union All, is there any other way to do it?
ID
1
1
1
2
3
3
4
4
4
4
Return
1
1
1
2
3
3
4
You can use ranking- and aggregate functions:
WITH CTE AS
(
SELECT ID,
CNT = COUNT(*) OVER (PARTITION BY ID),
RN = ROW_NUMBER() OVER (PARTITION BY ID ORDER BY ID)
FROM dbo.TableName
)
SELECT ID
FROM CTE
WHERE CNT <= 3 OR RN = 1
Demo
I'd do it like this
SELECT
GroupedData.ID
FROM
(SELECT ID, CNT = COUNT(*)
FROM dbo.TableName
GROUP BY ID) GroupedData AS g
LEFT JOIN dbo.TableName AS t
ON t.id = g.id and g.CNT<=3
This also allows you to add further columns which report details for the group or individual record as appropriate
SELECT
g.ID,
ISNULL(t.RecordName,'Grouped Records') as RecordName,
ISNULL(t.NumericField,g.NumericField) as NumericField
FROM
(
SELECT ID, CNT = COUNT(*), SUM(NumericField) as NumericField
FROM dbo.TableName
GROUP BY ID
) GroupedData AS g
LEFT JOIN dbo.TableName AS t
ON t.id = g.id and g.CNT<=3
Tabls is
ID Count
1 30
2 30
3 10
4 15
5 10
6 25
I want query which will give me
4 15
6 25
in result
You can use NOT EXISTS:
SELECT ID, Count
FROM dbo.TableName t1
WHERE NOT EXISTS
(
SELECT 1 FROM dbo.TableName t2
WHERE t1.ID <> t2.ID AND t1.Count = t2.Count
)
Demo
The following should select what you want:
SELECT t.ID, t.[Count]
FROM Table t
WHERE
(SELECT COUNT(*) FROM Table t1 WHERE t1.[Count] = t.[Count]) = 1
Please note that you should really have an index on Table.[Count].
you could also do it with a grouping statement
SELECT MIN(ID), Count
FROM Table
GROUP BY Count
HAVING COUNT(*) = 1
Use HAVING together with COUNT DISTINCT, to limit the result:
SELECT [Id], [Count]
FROM MyTable
WHERE [Count] IN (
SELECT [Count]
FROM MyTable
GROUP BY [Count]
HAVING COUNT(DISTINCT [Count]) = 1
)
May be this is odd but i need to concatenate values of ActionId to corresponding group of roleId and Order by ActionID is must., some thing like
ActionID RoleId
"1357" 1
"2468" 2
Here is what i have currently, I am looking for GROUP_CONCAT equivalent in MS SQL.
select av.ActionId, ra.RoleId from RoleAction ra join ActionValue av
on ra.ActionId = av.ActionId order by av.ActionId
ActionID RoleId
1 1
3 1
5 1
7 1
4 2
2 2
6 2
8 2
Is there way to do that? Thanks in advance.
You can make it work using FOR XML PATH('') and an inner query:
SELECT DISTINCT T1.RoleID,
(SELECT '' + ActionID
FROM RoleAction T2
WHERE T1.RoleID = T2.RoleID
ORDER BY ActionID
FOR XML PATH(''))
FROM RoleAction T1
This should work:
WITH CTE_A AS
(
select av.ActionId, ra.RoleId from RoleAction ra join ActionValue av
on ra.ActionId = av.ActionId
)
SELECT DISTINCT A.RoleId,
(SELECT '' +
CAST(B.ActionId AS varchar(10))
FROM CTE_A B
WHERE B.RoleID = A.RoleID
FOR XML PATH('')) AS ActionID
FROM CTE_A A
GROUP BY A.RoleID
I have a table with data
id name mgtId
--------------------------
1 joe null
2 jack 1
3 jill 1
4 paul 2
5 ron 4
6 sam 2
mgtId references id. How can I select non leaf nodes(joe, jack, paul) using CTE.
select *
from table
where id in (select mgtId from table)
One way:
;with parents_id as (
select distinct mgtId as id
from your_table
)
select *
from your_table t
inner join parants_id p on t.id = p.id
UPDATED 25 aprl 2012
I come to test above query and it works and also return root node:
select *
into #your_table
from (
select 1 as id, 'joe' as name, null as mgtId union all
select 2, 'jack ', 1 union all
select 3, 'jill ' , 1 union all
select 4, 'paul ' , 2 union all
select 5, 'ron ' , 4 union all
select 6, 'sam' , 2 ) T
;with parents_id as (
select distinct mgtId as id
from #your_table
)
select *
from #your_table t
inner join parents_id p on t.id = p.id
results:
id name mgtId id
-- ------- ----- --
1 joe null 1
2 jack 1 2
4 paul 2 4
with cte as(
select id,mgtId from mgr_emp
)
select b.id,b.name ,b.mgtId ,a.mgtId from cte a right join mgr_emp b
on b.mgtId =a.id