确定特定列上重复的表条目数的最佳方法

时间:2013-09-03 16:36:32

标签: sql sql-server performance tsql azure-sql-database

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

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 个答案:

答案 0 :(得分: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

你可以添加一个HAVING cnt>如果你想只过滤dupplicates,那么在GROUP BY子句之后为1。

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

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

答案 1 :(得分: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

答案 2 :(得分:1)

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

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

OR

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开始,每个分区的第一行。

答案 3 :(得分: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];

亚历山大的解决方案可能更好 肯定是代码少了