MS SQL Advanced Select 交换了一些东西

MS SQL Advanced Select where something has been swapped

我的问题是我需要找到在两家公司之间交换超过2次的客户,所以:

我们有公司 A 和 B,其 ID 例如为 1 和 2。 客户已从公司 A 调至公司 B,已记录到另一个 table 历史记录。

现在我需要 Select 已经从公司 A 调换到 B 然后从公司 B 调到 A 然后再从公司 A 调到 B(最后两次调换)的客户

我需要说我不知道​​该怎么做。有任何想法吗? 非常感谢每一个答案。

编辑:

@jarlh 示例:

Table Clients
ID        Name       CompanyId
1         Pikachu     63
2         Mew          34
3         Reptide     63

Table历史

ID   ClientId   CompanyId
1     1            34
2     1            63
3     1            34
4     1            63
5     2            34
6     2            73
7     2            34
8     2            34
9     3            34
10    3            84
11    3             63
12    3            34
13    3            34
14    3            63

结果:

Id       ClientId
1        1
2        3

如果你的两家公司是固定的,你只想要一个方向A->B->A,不关心B->A->B,你可以从History中找到所有有公司B和之前和之后都存在于A

类似于:

SELECT * FROM HistoryTable ht
WHERE CompanyID = 63 
AND EXISTS (SELECT * FROM HistoryTable h1 
            WHERE h1.ClientID = ht.ClientID 
            AND h1.CompanyID = 34
            AND h1.ID < ht.ID)
AND EXISTS (SELECT * FROM HistoryTable h2 
            WHERE h2.ClientID = ht.ClientID 
            AND h2.CompanyID = 34
            AND h2.ID > ht.ID)

编辑: 有 3 次交换,它变得有点复杂:

SELECT * FROM HistoryTable ht 
WHERE CompanyID IN (63,34)
AND EXISTS (SELECT * FROM HistoryTable h1 
            WHERE h1.ClientID = ht.ClientID 
            AND h1.CompanyID IN (34,63)
            AND h1.CompanyID <> ht.CompanyID
            AND h1.ID < ht.ID)
AND EXISTS (SELECT * FROM HistoryTable h2 
            WHERE h2.ClientID = ht.ClientID 
            AND h2.CompanyID IN (34,63)
            AND h2.CompanyID <> ht.CompanyID
            AND h2.ID > ht.ID
            AND EXISTS (SELECT * FROM HistoryTable h3 
                        WHERE h3.ClientID = h2.ClientID 
                        AND h3.CompanyID IN (34,63)
                        AND h3.CompanyID <> h2.CompanyID
                        AND h3.ID > h2.ID))

我还添加了双向交换。 在 A->B->A->B 的情况下,ht table 应该代表 B - 第二家公司,我们检查它之前是否存在 A (h1),以及它之后是否存在 A (h2)它本身也有 B (h3)

最简单的方法就是将您的历史记录 table 自身连接 4 次,然后使用连接和位置过滤结果。它会工作,但在性能方面非常糟糕。仅当您没有大量数据或不着急时才使用它。

SELECT * FROM HistoryTable h1
INNER JOIN HistoryTable h2 ON h2.ClientID = h1.ClientID 
                           AND h2.Id >h1.ID 
                           AND h2.CompanyID <> h1.CompanyID
INNER JOIN HistoryTable h3 ON h3.ClientID = h2.ClientID 
                           AND h3.Id >h2.ID 
                           AND h3.CompanyID = h1.CompanyID
INNER JOIN HistoryTable h4 ON h4.ClientID = h3.ClientID 
                           AND h4.Id >h3.ID 
                           AND h4.CompanyID = h2.CompanyID
WHERE h1.CompanyID IN (34,63)
AND h2.CompanyID IN (34,63)