MS SQL高级选择已交换内容的位置

MS SQL高级选择已交换内容的位置,sql,sql-server,select,where,Sql,Sql Server,Select,Where,我的问题是,我需要找到在两家公司之间交换超过2次的客户,因此: 我们有A公司和B公司的ID,例如1和2。 客户机已从A公司交换到B公司,它已记录到另一个历史记录表中 现在我需要选择从A公司交换到B公司的客户,然后从B公司交换到A公司,最后再从A公司交换到B公司 我得说我不知道怎么做。有什么想法吗? 非常感谢你的每一个回答 编辑: @例如: Table Clients ID Name CompanyId 1 Pikachu 63 2

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

我们有A公司和B公司的ID,例如1和2。 客户机已从A公司交换到B公司,它已记录到另一个历史记录表中

现在我需要选择从A公司交换到B公司的客户,然后从B公司交换到A公司,最后再从A公司交换到B公司

我得说我不知道怎么做。有什么想法吗? 非常感谢你的每一个回答

编辑:

@例如:

Table Clients
ID        Name       CompanyId
1         Pikachu     63
2         Mew          34
3         Reptide     63
表格历史记录

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,你可以从历史中找到所有在这之前和之后都存在于A的公司B

比如:

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表应该代表B-2nd公司,我们检查是否在h1之前存在A,以及在h2之后是否存在A,并且在h3之后也有B。最简单的方法是将历史表自身连接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)

添加表定义、一些示例表数据和预期结果。并向我们展示您的查询尝试。您是否只有两家公司?到底是三次互换还是两次以上的互换?总是A,然后B,然后A,还是这只是一个例子?@Frode在数据库中我有更多的公司,但我只需要在两个特定的一个静态id之间进行交换,比如在示例A公司id 34和B公司id 63中,一个客户id的不同公司id永远不会超过2个?@jarlh有,看看3号客户的例子,他在34号公司,然后是84号公司,然后是63号公司,再回到34号公司,然后又是34号公司,有可能在同一家公司再签合同,然后又是63号公司,这就是脚本应该产生他的地方,因为他在34号公司,然后忽略84 where子句?他到了63岁,又回到了34岁,最后又回到了63岁。我需要的客户是A->B->A->B或B->A->B->A@Zefurion:好的,有很多方法可以做到,您可以加入HistoryTable 4次,然后以一种简单但性能不佳的方式进行筛选,或者您可以使用滞后函数。如果我有时间的话,我会用不同的答案给你这些示例代码。问题是我有很多数据,超过10万的历史数据。。。最后,我只需要在历史记录表中有情况的结果客户,比如A>B>A>B。我正在考虑在Select或Select in Where子句中使用Select,但我不知道我是否正确,是否有可能这样做。非常感谢您的回答!最后:没有快速过滤100k行的方法,无论哪种方法,您都需要检查所有行,并多次检查。可能您将上面的查询拆分为4个查询,在这4个查询之间过滤一个新的临时表。在第一张临时表中填写在任一公司工作的可能客户。然后加入,找出那些切换过一次的人,填写第二张临时表。。以此类推..是否可以像下面那样通过和存在来执行A->B->A->B?@Zefurion是的,但是有3个更改会变得更复杂。您需要在子查询中存在嵌套的查询。我会试着为你重写它。