1

我需要确定特定表行在特定列上是否唯一。目前我正在使用这样的子查询来执行此操作:

SELECT
    t1.ID,
    (SELECT COUNT(*)
        FROM MyTable AS t2
        WHERE (t2.FirstName = t1.FirstName) AND (t2.Surname = t1.Surname)
    ) AS cnt
FROM MyTable AS t1
WHERE t1.ID IN (100, 101, 102);

哪个工作正常。但是,我想知道是否有人知道比使用子查询更有效的方法来获得相同的结果。

顺便说一句,我正在 Azure SQL Server 上执行此操作。

4

4 回答 4

2

你可以像这样使用一个组:

SELECT
    t1.FirstName,
    t1.Surname,
    COUNT(t1.ID) as cnt
FROM MyTable AS t1
WHERE t1.ID IN (100, 101, 102)
GROUP BY t1.FirstName, t1.Surname
ORDER BY cnt DESC

如果您只想过滤重复项,可以在 GROUP BY 子句之后添加 HAVING cnt > 1。

但是,这取决于您是否还需要 ID 列,如果需要,您可能必须使用子查询。

在这里您可以找到有关该主题的更多信息: http ://technet.microsoft.com/en-us/library/ms177673.aspx

于 2013-09-03T16:47:50.220 回答
1

我认为更有效的方法是使用带有 OVER 子句的 COUNT 函数或 ROW_NUMBER 排名函数

SELECT ID, COUNT(*) OVER(PARTITION BY FirstName, Surname) AS cnt
FROM MyTable
WHERE ID IN (100, 101, 102)

或者

SELECT ID, ROW_NUMBER() OVER(PARTITION BY FirstName, Surname ORDER BY ID) AS rn
FROM MyTable
WHERE ID IN (100, 101, 102)

ROW_NUMBER 返回结果集分区内行的序号,每个分区的第一行从 1 开始。

于 2013-09-03T18:25:18.267 回答
1

我不知道这将如何与您在您的环境中的查询进行比较,但我希望这会表现得更好:

Select id, qty
From mytable
Inner join
(
    Select firstname, surname, count(0) as qty
    From mytable
    Group by firstname, surname
) as qtytable
On mytable.firstname = qtytable.firstname  and mytable.surname = qtytable.surname
于 2013-09-03T17:00:47.093 回答
0

有点极端,但由于需要使用 IN (100, 101, 102) 两次然后创建#temp

CREATE TABLE #temp(
    [ID] [int] NOT NULL,
    [fname] [varchar](50) NOT NULL,
    [lname] [varchar](50) NOT NULL);

insert into #temp([ID],[fname],[lname])
SELECT ID, FirstName, Surname 
FROM MyTable
WHERE ID IN (100, 101, 102);

select t1.ID, t2.count 
from #temp as t1
join 
(
  select [fname],[lname], count(*) as count 
    from #temp 
   group by [fname],[lname]
) as t2
 on t1.[fname] = t2.[fname]
and t1.[lname] = t2.[lname];

Alexander 的解决方案可能更好一些
肯定是更少的代码

于 2013-09-03T17:51:14.480 回答