Sql server SQL Server使用不同的值在两列中统计数据

Sql server SQL Server使用不同的值在两列中统计数据,sql-server,tsql,Sql Server,Tsql,我想做一个智能计数操作,这样如果列中的数据相同,那么它将被计数为1 我的桌子是: dbo.Messages ( FromUserId INT, ToUserId INT ) 数据: 计数应该返回2,因为1,5和5,1在我的算法中是相同的 如何在SQL Server TSQL中编写它 提前感谢。一种方法是使用原始表中的不同值,按FromUserId和ToUserId中最小和最大的值分组。与MySQL不同,SQL Server没有最小和最大的函数,因此我们可以使用CASE表达式

我想做一个智能计数操作,这样如果列中的数据相同,那么它将被计数为1

我的桌子是:

dbo.Messages 
(
    FromUserId INT,
    ToUserId INT
)
数据:

计数应该返回2,因为1,5和5,1在我的算法中是相同的

如何在SQL Server TSQL中编写它


提前感谢。

一种方法是使用原始表中的不同值,按FromUserId和ToUserId中最小和最大的值分组。与MySQL不同,SQL Server没有最小和最大的函数,因此我们可以使用CASE表达式

SELECT CASE WHEN t.FromUserId < t.ToUserId THEN t.FromUserId ELSE t.ToUserId END,
       CASE WHEN t.FromUserId < t.ToUserId THEN t.ToUserId   ELSE t.FromUserId END,
       COUNT(*) AS duplicateCount
FROM
(
    SELECT DISTINCT FromUserId, ToUserId
    FROM dbo.Messages
) t
GROUP BY CASE WHEN t.FromUserId < t.ToUserId THEN t.FromUserId ELSE t.ToUserId END,
         CASE WHEN t.FromUserId < t.ToUserId THEN t.ToUserId   ELSE t.FromUserId END
这很有效:

CREATE TABLE #Messages 
(
    FromUserId INT,
    ToUserId INT
);

INSERT #Messages VALUES(1, 5), (2, 20), (5, 1), (1, 5);

SELECT COUNT(*)
FROM (
  SELECT M1.FromUserId, M1.ToUserId
  FROM #Messages AS M1
  EXCEPT
  SELECT M2.ToUserId, M2.FromUserId
  FROM #Messages AS M2
  WHERE M2.ToUserId > M2.FromUserId
  ) AS T;
带有EXCEPT的派生表将删除重复项,然后它只计算所谓的唯一值。请记住,除了删除所有重复项之外,这里不需要使用不同的关键字

派生表的结果:

FromUserId ToUserId 
---------- -------- 
1          5        
2          20   

您可以在此处检查此查询的工作方式:

在SQL Server 2008及更高版本上,这应该可以工作:

SELECT distinct
    (SELECT Min(v) FROM (VALUES (FromUserId), (ToUserId)) AS value(v)) as UserIdMin,
    (SELECT Max(v) FROM (VALUES (FromUserId), (ToUserId)) AS value(v)) as UserIdMax
FROM dbo.Messages

信用证:

我认为它不符合A/C。如果您删除计数并保持唯一性,它会返回1和5,这似乎是错误的。1,5和5,1应该被视为相同的。@EvaldasBuinauskas:用户要求计数,在本例中返回2,您是否看到了演示。但碰巧它带来了2。编辑数据后,您的查询将不再有效。它将返回不正确的计数。@EvaldasBuinauskas:谢谢,我在想用户问题中的这一行,whole time count应该返回2,现在更新这是一个很好的答案。要添加内容,不需要两个单独的子查询,可以使用交叉应用来返回最小值和最大值。下面是一个例子:
FromUserId ToUserId 
---------- -------- 
1          5        
2          20   
SELECT distinct
    (SELECT Min(v) FROM (VALUES (FromUserId), (ToUserId)) AS value(v)) as UserIdMin,
    (SELECT Max(v) FROM (VALUES (FromUserId), (ToUserId)) AS value(v)) as UserIdMax
FROM dbo.Messages