Sql 运行查询以查找两个字段相同的位置的最快方法是什么

Sql 运行查询以查找两个字段相同的位置的最快方法是什么,sql,sql-server,Sql,Sql Server,我有一个id为first、last的表,我想运行一个查询 给我每一条第一个和最后一个组合存在不止一次的记录 我正在尝试查找重复记录从具有count*>1个组的表中选择count*,按concatfirst,last从具有count*>1个组的表中选择count*,按concatfirst,last编辑 连接将给出错误的答案,正如“罗伯托·尼尔”对“罗伯特·奥尼尔”的评论中所指出的那样 下面是一个解决级联问题的答案。我找到了非重复项,并从最终答案中删除了它们 WITH MyTable AS (

我有一个id为first、last的表,我想运行一个查询

给我每一条第一个和最后一个组合存在不止一次的记录

我正在尝试查找重复记录

从具有count*>1个组的表中选择count*,按concatfirst,last

从具有count*>1个组的表中选择count*,按concatfirst,last

编辑 连接将给出错误的答案,正如“罗伯托·尼尔”对“罗伯特·奥尼尔”的评论中所指出的那样

下面是一个解决级联问题的答案。我找到了非重复项,并从最终答案中删除了它们

WITH MyTable AS
(
    SELECT 1 as ID, 'John' as FirstName, 'Doe' as LastName
    UNION
    SELECT 2 as ID, 'John' as FirstName, 'Doe' as LastName
    UNION
    SELECT 3 as ID, 'Tim' as FirstName, 'Doe' as LastName
    UNION
    SELECT 4 as ID, 'Jane' as FirstName, 'Doe' as LastName
    UNION
    SELECT 5 as ID, 'Jane' as FirstName, 'Doe' as LastName
)
SELECT Id, FirstName, LastName
FROM MyTable SelectTable
WHERE Id Not In
(
    SELECT Min (Id)
    From MyTable SearchTable
    GROUP BY FirstName, LastName
    HAVING COUNT (*) = 1
)
老办法 使用分组方式并拥有。。看看这个工作样本

WITH MyTable AS
(
SELECT 1 as ID, 'John' as FirstName, 'Doe' as LastName
UNION
SELECT 2 as ID, 'John' as FirstName, 'Doe' as LastName
UNION
SELECT 3 as ID, 'Time' as FirstName, 'Doe' as LastName
UNION
SELECT 4 as ID, 'Jane' as FirstName, 'Doe' as LastName
)
SELECT ID, FirstName, LastName
FROM MyTable
WHERE FirstName + LastName IN
(
    SELECT FirstName + LastName
    FROM MyTable
    GROUP BY FirstName + LastName
    HAVING COUNT (*) > 1
)
这将导致以下结果:

ID          FirstName LastName
----------- --------- --------
1           John      Doe
2           John      Doe
编辑 连接将给出错误的答案,正如“罗伯托·尼尔”对“罗伯特·奥尼尔”的评论中所指出的那样

下面是一个解决级联问题的答案。我找到了非重复项,并从最终答案中删除了它们

WITH MyTable AS
(
    SELECT 1 as ID, 'John' as FirstName, 'Doe' as LastName
    UNION
    SELECT 2 as ID, 'John' as FirstName, 'Doe' as LastName
    UNION
    SELECT 3 as ID, 'Tim' as FirstName, 'Doe' as LastName
    UNION
    SELECT 4 as ID, 'Jane' as FirstName, 'Doe' as LastName
    UNION
    SELECT 5 as ID, 'Jane' as FirstName, 'Doe' as LastName
)
SELECT Id, FirstName, LastName
FROM MyTable SelectTable
WHERE Id Not In
(
    SELECT Min (Id)
    From MyTable SearchTable
    GROUP BY FirstName, LastName
    HAVING COUNT (*) = 1
)
老办法 使用分组方式并拥有。。看看这个工作样本

WITH MyTable AS
(
SELECT 1 as ID, 'John' as FirstName, 'Doe' as LastName
UNION
SELECT 2 as ID, 'John' as FirstName, 'Doe' as LastName
UNION
SELECT 3 as ID, 'Time' as FirstName, 'Doe' as LastName
UNION
SELECT 4 as ID, 'Jane' as FirstName, 'Doe' as LastName
)
SELECT ID, FirstName, LastName
FROM MyTable
WHERE FirstName + LastName IN
(
    SELECT FirstName + LastName
    FROM MyTable
    GROUP BY FirstName + LastName
    HAVING COUNT (*) > 1
)
这将导致以下结果:

ID          FirstName LastName
----------- --------- --------
1           John      Doe
2           John      Doe
未经测试:

SELECT name, count(*) from (
   SELECT id, first+last as [name]
   from table) t
HAVING count(*) >1
未经测试:

SELECT name, count(*) from (
   SELECT id, first+last as [name]
   from table) t
HAVING count(*) >1

您还可以使用窗口功能。这将比Raj More的解决方案略好:

with MyTable as
(
    select 1 as ID, 'John' as FirstName, 'Doe' as LastName
    union
    select 2 as ID, 'John' as FirstName, 'Doe' as LastName
    union
    select 3 as ID, 'Time' as FirstName, 'Doe' as LastName
    union
    select 4 as ID, 'Jane' as FirstName, 'Doe' as LastName
)
select * 
from (
    select *, cnt = count(*) over ( partition by FirstName, LastName )
    from MyTable
) x
where x.cnt > 1

您还可以使用窗口功能。这将比Raj More的解决方案略好:

with MyTable as
(
    select 1 as ID, 'John' as FirstName, 'Doe' as LastName
    union
    select 2 as ID, 'John' as FirstName, 'Doe' as LastName
    union
    select 3 as ID, 'Time' as FirstName, 'Doe' as LastName
    union
    select 4 as ID, 'Jane' as FirstName, 'Doe' as LastName
)
select * 
from (
    select *, cnt = count(*) over ( partition by FirstName, LastName )
    from MyTable
) x
where x.cnt > 1

这里有两种可能的解决方案。哪个更快可能取决于您的索引和数据,所以请尝试这两种方法,看看哪种方法更适合您。但在大多数情况下,我相信第一个查询会更快

SELECT
    T1.id
FROM
    My_Table T1
INNER JOIN
(
    SELECT
        first_name,
        last_name
    FROM
        My_Table T2
    GROUP BY
        first_name,
        last_name
    HAVING
        COUNT(*) > 1
) SQ ON
    SQ.first_name = T1.first_name AND
    SQ.last_name = T1.last_name

SELECT
    T1.id
FROM
    My_Table T1
WHERE
    EXISTS
    (
        SELECT *
        FROM
            My_Table T2
        WHERE
            T2.first_name = T1.first_name AND
            T2.last_name = T1.last_name AND
            T2.id <> T1.id
    )

这里有两种可能的解决方案。哪个更快可能取决于您的索引和数据,所以请尝试这两种方法,看看哪种方法更适合您。但在大多数情况下,我相信第一个查询会更快

SELECT
    T1.id
FROM
    My_Table T1
INNER JOIN
(
    SELECT
        first_name,
        last_name
    FROM
        My_Table T2
    GROUP BY
        first_name,
        last_name
    HAVING
        COUNT(*) > 1
) SQ ON
    SQ.first_name = T1.first_name AND
    SQ.last_name = T1.last_name

SELECT
    T1.id
FROM
    My_Table T1
WHERE
    EXISTS
    (
        SELECT *
        FROM
            My_Table T2
        WHERE
            T2.first_name = T1.first_name AND
            T2.last_name = T1.last_name AND
            T2.id <> T1.id
    )

关闭-您不能选择ID,因为它不在agg函数中,您可以选择Lastname或firstname。如果你更新答案,我将标记为correct@ooo:我也意识到了!我刚刚更正了答案,并给了你一个工作示例。这样连接名称可能会导致误报。例如,Robert While和Rob Ertwile@Tom H。感谢您指出我的错误。Answer corrected.close-您不能选择ID,因为它不在agg函数中,您可以选择Lastname或firstname。如果你更新答案,我将标记为correct@ooo:我也意识到了!我刚刚更正了答案,并给了你一个工作示例。这样连接名称可能会导致误报。例如,Robert While和Rob Ertwile@Tom H。感谢您指出我的错误。答案已更正。此语法无效。没有分组依据,因此不能使用having。此语法无效。没有分组方式,所以不能使用分组方式。