比较一个表中的两个选择值

时间:2012-04-26 06:59:02

标签: sql sql-server sql-server-2008 tsql

这是我的表:

MyTable Id, Title, Point, Date

因此,我需要检查Title = 'member1'的所有点和日期是否等于Title = 'member2'的所有点和日期然后Set @flag = 1否则Set @flag = 0精确二选择是:

Select Point, Date From MyTable Where Title = 'member1'

Select Point, Date From MyTable Where Title = 'member2'

如果相同或不相同,我需要检查所有行。你的建议是什么?

更新

假设以下示例:

Title  Point     Date

T1      1   2012-04-26 07:14:34.000
T1      2   2012-07-26 07:14:34.000
T1      3   2012-06-26 07:14:34.000
T1      4   2012-05-26 07:14:34.000
T2      1   2012-04-26 07:14:34.000
T2      2   2012-07-26 07:14:34.000
T2      3   2012-06-26 07:14:34.000
T2      4   2012-05-26 07:14:34.000
T3      4   2012-05-26 07:14:34.000
T3      3   2012-06-26 07:14:34.000
T4      1   2012-04-26 07:14:34.000
T4      2   2012-07-26 07:14:34.000
T4      3   2012-06-26 07:14:34.000
T4      4   2012-05-27 07:14:34.000 -- 26 to 27
T5      2   2012-12-27 07:14:34.000
T5      6   2012-05-27 07:14:34.000
T5      3   2012-07-26 07:14:34.000

在这个例子中,只有T1值和T2值相等而其他值不相等。

3 个答案:

答案 0 :(得分:1)

我猜您需要检查会员2中是否缺少会员1,反之亦然,因此您需要检查两种方式。如果你在一系列日期之间这样做(下面的代码将是所有日期),可以在一次通过中使用整数表来完成,并且效率更高。

IF NOT EXISTS (
SELECT
    Point,
    Date
FROM 
    MyTable aa
LEFT OUTER JOIN MyTable bb
ON aa.point = bb.point
AND aa.date = bb.date

WHERE 
    aa.title = 'member1'
AND bb.title = 'member2'
AND bb.title IS NULL

UNION 

SELECT
    Point,
    Date
FROM 
    MyTable aa
LEFT OUTER JOIN MyTable bb
ON aa.point = bb.point
AND aa.date = bb.date

WHERE 
    aa.title = 'member2'
AND bb.title = 'member1'
AND bb.title IS NULL
)
SELECT @Flag = 1

答案 1 :(得分:1)

我将如何做到这一点。计划是获取每个结果集,然后将其转换为XML并比较两个XML结果。更容易(在我看来)。

CREATE TABLE MyTable
(
[id] integer identity,
[Title] varchar(1024),
[Point] int,
[Date] datetime
);


insert into MyTable([Title], [Point], [Date])
values('T1',      1,   '2012-04-26 07:14:34.000'),
('T1',      2,   '2012-07-26 07:14:34.000'),
('T1',      3,   '2012-06-26 07:14:34.000'),
('T1',      4,   '2012-05-26 07:14:34.000'),
('T2',      1,   '2012-04-26 07:14:34.000'),
('T2',      2,   '2012-07-26 07:14:34.000'),
('T2',      3,   '2012-06-26 07:14:34.000'),
('T2',      4,   '2012-05-26 07:14:34.000'),
('T3',      4,   '2012-05-26 07:14:34.000'),
('T3',      3,   '2012-06-26 07:14:34.000'),
('T4',      1,   '2012-04-26 07:14:34.000'),
('T4',      2,   '2012-07-26 07:14:34.000'),
('T4',      3,   '2012-06-26 07:14:34.000'),
('T4',      4,   '2012-05-27 07:14:34.000'),
('T5',      2,   '2012-12-27 07:14:34.000'),
('T5',      6,   '2012-05-27 07:14:34.000'),
('T5',      3,   '2012-07-26 07:14:34.000');

-- your original queries
Select Point, Date From MyTable Where Title = 'T1';
Select Point, Date From MyTable Where Title = 'T2';

-- first I am going to just get each one as XML
SELECT [Point], [Date]
FROM MyTable 
WHERE Title = 'T1'
FOR XML PATH('');


SELECT [Point], [Date]
FROM MyTable 
WHERE Title = 'T2'
FOR XML PATH('');



-- first just get the two results into one result set
select t.FirstCheck, t.SecondCheck
from (
    select (SELECT [Point], [Date]
              FROM MyTable 
             WHERE Title = 'T1'
               FOR XML PATH('')) as FirstCheck,
           (SELECT [Point], [Date]
              FROM MyTable 
             WHERE Title = 'T2'
               FOR XML PATH('')) as SecondCheck
) as t;


-- now for the real check.

declare @flag int;

select @flag = case when t.FirstCheck = t.SecondCheck  then 1 else 0 end 
from (
    select (SELECT [Point], [Date]
              FROM MyTable 
             WHERE Title = 'T1'
               FOR XML PATH('')) as FirstCheck,
           (SELECT [Point], [Date]
              FROM MyTable 
             WHERE Title = 'T2'
               FOR XML PATH('')) as SecondCheck
) as t;
-- this should return 1
select @flag as Flag;


select @flag = case when t.FirstCheck = t.SecondCheck  then 1 else 0 end 
from (
    select (SELECT [Point], [Date]
              FROM MyTable 
             WHERE Title = 'T1'
               FOR XML PATH('')) as FirstCheck,
           (SELECT [Point], [Date]
              FROM MyTable 
             WHERE Title = 'T3'
               FOR XML PATH('')) as SecondCheck
) as t;
-- this should return 0
select @flag as Flag;

如果我明白你要做什么,那就应该这样做。

答案 2 :(得分:0)

这不会赢得任何美容或表演比赛,但它应该足够了。它的要点是

  • 计算每个标题
  • 在您要比较的所有字段上加入MyTable
  • 加入各自的统计表
  • 仅选择两个计数匹配的结果

SQL声明

;WITH cnt (Title, cnt) AS (
  SELECT  Title, COUNT(*)
  FROM    MyTable
  GROUP BY
          Title
)  
SELECT  DISTINCT mt1.Title
        , mt2.Title
FROM    MyTable mt1
        INNER JOIN MyTable mt2 ON mt1.Point = mt2.Point 
                                  AND mt1.Date = mt2.Date 
                                  AND mt1.Title < mt2.Title
        INNER JOIN cnt cnt1 ON cnt1.Title = mt1.Title
        INNER JOIN cnt cnt2 ON cnt2.Title = mt2.Title        
WHERE   cnt1.cnt = cnt2.cnt