簡體   English   中英

SQL-確保一組鍵對中表示的兩個實體都存在於最終數據集中的有效方法

[英]SQL - Efficient way to make sure both entities represented in a set of key Keypairs exist in final dataset

問題:如何有效地獲得一組匹配的人的列表(下面的#People表,每行一個人)(下面的#Keys表),還要確保這些集合是唯一的。

背景:我正在處理數據庫中的匹配項集(以KeyId,PersonId1,PersonId2的形式)。 我們有一種自動方法,可將人標記為重復項並將其寫入匹配表。 人數不多,但我們通常坐着大約10萬場比賽記錄和20萬名球員。 匹配過程還添加了重復記錄,形式是將Person 1與2匹配,也將2與1匹配。此外,我們在邏輯上刪除人員記錄(IsDeleted = 1),所以不想返回已經有一個人員的匹配項已刪除。

我們有一個管理屏幕,人們可以在其中查看重復項,並標記它們是否不是重復項,或刪除其中之一。 存在一個問題,即使刪除了該對中的一個人,另一個人仍顯示在列表中。 下面的SQL試圖確保僅返回作為集合存在的人員。

測試數據設置:

CREATE TABLE #Keys
(
    KeyId int PRIMARY KEY,
    PersonId1 int,
    PersonId2 int
)

CREATE TABLE #People
(
    PersonId int PRIMARY KEY,
    Name varchar(150),
    IsDeleted bit
)

INSERT INTO #People
VALUES  (1, 'John',0),
        (2, 'Madeline',0),
        (3, 'Ralph',1),
        (4, 'Sarah',0),
        (5, 'Jack',0),
        (6, 'Olivia',0),
        (7, 'Ethan',0),
        (8, 'Sophia',0)

INSERT INTO #Keys
VALUES  (1,1,2),
        (2,2,3),
        (3,1,3),
        (4,2,1),
        (5,4,8),
        (6,3,7),
        (7,6,1)

SELECT *
FROM #Keys k
 JOIN #People p1
    ON k.PersonId1 = p1.PersonId
    AND p1.IsDeleted = 0
 JOIN #People p2
    ON k.PersonId2 = p2.PersonId
    AND p2.IsDeleted = 0

返回值:

KeyId   PersonId1   PersonId2   PersonId    Name    IsDeleted   PersonId    Name    IsDeleted
1   1   2   1   John    0   2   Madeline    0
4   2   1   2   Madeline    0   1   John    0
5   4   8   4   Sarah   0   8   Sophia  0
7   6   1   6   Olivia  0   1   John    0



SELECT KeyId, p1.PersonId, p1.Name
INTO #Results
FROM #Keys k
 JOIN #People p1
    ON k.PersonId1 = p1.PersonId
    AND p1.IsDeleted = 0
 JOIN #People p2
    ON k.PersonId2 = p2.PersonId
    AND p2.IsDeleted = 0

INSERT INTO #Results
SELECT KeyId, p2.PersonId, p2.Name
FROM #Keys k
 JOIN #People p1
    ON k.PersonId1 = p1.PersonId
    AND p1.IsDeleted = 0
 JOIN #People p2
    ON k.PersonId2 = p2.PersonId
    AND p2.IsDeleted = 0

SELECT * from #Results
order by KeyId

DROP TABLE #People
DROP TABLE #Keys
DROP TABLE #Results

最終查詢返回以下集合:

KeyId   PersonId    Name
1   2   Madeline
1   1   John
4   2   Madeline
4   1   John
5   8   Sophia
5   4   Sarah
7   6   Olivia
7   1   John

但是,問題在於鍵1和鍵4具有相同的人員,只是順序相反。 我想要返回的集合是:

KeyId   PersonId    Name
1   2   Madeline
1   1   John
5   4   Sarah
5   8   Sophia
7   1   John
7   6   Olivia

首先我會

PersonId1 int,
PersonId2 int

#Keys上的PK並放下KeyId

快速獲得獨特的方法

select PersonId1, PersonId2 
from keys 
where PersonId1 < PersonId2 
union 
select PersonId2, PersonId1 
from keys 
where PersonId2 < PersonId1 

顯然,您需要在刪除時添加聯接

您還可以對#Keys施加一個約束,使PersonId1 <PersonId2

我認為這也會起作用

select PersonId1, PersonId2 from keys 
except 
select PersonId2, PersonId1 from keys 

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM