简体   繁体   中英

How to select rows based on column value is repeating and has different values in another column

I need to query a table in order to return rows, but I'm not able to query the table correctly. Here is my table view:

Id  Name    Date        Subject     TrackingToken   RegardingObjectId                       Type    TypeName
1   XXXX    8/26/2015   RE: XXXXXX  CRM:0030062     496BF810-4DBE-E311-9357-00505686395E    112 RE: YYYY
1   XXXX    8/27/2015   RE: XXXXXX  CRM:0030055     AA8C2F71-CDD1-E311-894A-005056863ADA    112 RE: YYYY
1   XXXX    8/28/2015   RE: XXXXXX  CRM:0030055     4DF02C89-2FBE-E311-9357-00505686395E    112 RE: YYYY
1   XXXX    8/29/2015   RE: XXXXXX  CRM:0030049     496BF810-4DBE-E311-9357-00505686395E    112 RE: YYYY
1   XXXX    8/30/2015   RE: XXXXXX  CRM:0030049     06393EF9-71CC-E311-894A-005056863ADA    112 RE: YYYY
1   XXXX    8/31/2015   RE: XXXXXX  CRM:0030047     8BE51823-52BE-E311-9357-00505686395E    112 RE: YYYY
1   XXXX    9/1/2015    RE: XXXXXX  CRM:0030003     6ABE11CA-BABF-E311-89E9-005056863ADA    112 RE: YYYY

The result set should return:

Id  Name    Date        Subject     TrackingToken   RegardingObjectId                       Type    TypeName
1   XXXX    8/27/2015   RE: XXXXXX  CRM:0030055     AA8C2F71-CDD1-E311-894A-005056863ADA    112 RE: YYYY
1   XXXX    8/28/2015   RE: XXXXXX  CRM:0030055     4DF02C89-2FBE-E311-9357-00505686395E    112 RE: YYYY
1   XXXX    8/29/2015   RE: XXXXXX  CRM:0030049     496BF810-4DBE-E311-9357-00505686395E    112 RE: YYYY
1   XXXX    8/30/2015   RE: XXXXXX  CRM:0030049     06393EF9-71CC-E311-894A-005056863ADA    112 RE: YYYY

In other words: Select all records where column TrackingToken is repeating and RegardingObjectId has different value.

Current Query:

select [OwnerId],[OwnerIdName],[CreatedOn],[Subject],
[TrackingToken],[RegardingObjectId],
[RegardingObjectTypeCode],[RegardingObjectIdName]

from [TableX].[dbo].[Email] a
where not exists (select [TrackingToken], [RegardingObjectId]
                  from [TableX].[dbo].[Email] b
                  where a.[TrackingToken] = b.[TrackingToken]
                    and a.[RegardingObjectId] = b.[RegardingObjectId]
                    AND RegardingObjectTypeCode = 112
                  group by [TrackingToken],[RegardingObjectId]
                  having count(*)> 1)
  and a.TrackingToken in (select TrackingToken
                          from [TableX].[dbo].[Email]
                          group by TrackingToken
                          having count(*) > 1)
  and a.RegardingObjectId is not null
  and a.RegardingObjectTypeCode = 112
  and a.TrackingToken is not null
order by a.TrackingToken desc

You can count the distinct number of [RegardingObjectId]:

select TrackingToken
from [TableX].[dbo].[Email]
group by TrackingToken
having count(distinct [RegardingObjectId]) > 1

You can use the analytic version of COUNT to count records over a certain range (within the TrackingToken in your case). Then only keep those records where the count of different RegardingObjectId is greater than one.

select *
from
(
  select mytable.* 
    , count(distinct regardingobjectid) over (partition by trackingtoken) as cnt
  from mytable
) counted
where cnt > 1;

EDIT: As Felix Pamittan pointed out, SQL Server doesn't fully support COUNT OVER, such that you cannot use DISTINCT with it. So here is the same with the normal COUNT aggregation:

select mytable.* 
from mytable
where 
(
  select count(distinct token.regardingobjectid) 
  from mytable token
  where token.trackingtoken = mytable.trackingtoken
) > 1;

Or without a correlated subquery, but a derived table instead:

select mytable.* 
from mytable
join
(
  select trackingtoken
  from mytable
  group by trackingtoken
  having count(distinct regardingobjectid) > 1
) tokens on tokens.trackingtoken = mytable.trackingtoken;

The below is a working example

CREATE TABLE #X(Id INT,Name NVARCHAR(8),Date DATE,Subject NVARCHAR(16),TrackingToken NVARCHAR(14),RegardingObjectId UNIQUEIDENTIFIER,Type INT,TypeName NVARCHAR(8))

INSERT INTO #X(Id,Name,Date,Subject,TrackingToken,RegardingObjectId,Type,TypeName)
VALUES
(1,'XXXX','8/26/2015','RE: XXXXXX','CRM:0030062','496BF810-4DBE-E311-9357-00505686395E',112,'RE: YYYY'),
(1,'XXXX','8/27/2015','RE: XXXXXX','CRM:0030055','AA8C2F71-CDD1-E311-894A-005056863ADA',112,'RE: YYYY'),
(1,'XXXX','8/28/2015','RE: XXXXXX','CRM:0030055','4DF02C89-2FBE-E311-9357-00505686395E',112,'RE: YYYY'),
(1,'XXXX','8/29/2015','RE: XXXXXX','CRM:0030049','496BF810-4DBE-E311-9357-00505686395E',112,'RE: YYYY'),
(1,'XXXX','8/30/2015','RE: XXXXXX','CRM:0030049','06393EF9-71CC-E311-894A-005056863ADA',112,'RE: YYYY'),
(1,'XXXX','8/31/2015','RE: XXXXXX','CRM:0030047','8BE51823-52BE-E311-9357-00505686395E',112,'RE: YYYY'),
(1,'XXXX','9/1/2015' ,'RE: XXXXXX','CRM:0030003','6ABE11CA-BABF-E311-89E9-005056863ADA',112,'RE: YYYY')

SELECT      A.*
FROM        #X AS A
INNER JOIN
    (
        SELECT      TrackingToken
        FROM        #X
        GROUP BY    TrackingToken
        HAVING      COUNT(*) > 1
    ) AS O ON O.TrackingToken = A.TrackingToken

DROP TABLE #X

You can optimize this by adding an index to the TrackingToken column

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM