更高效的SQL语句以消除我的n^2算法?

3

假设以下是我的SQL表:

我的第一个表叫做[Customer]

CustomerID    CustomerName    CustomerAddress
----------    ------------    ---------------
1             Name1           1 Infinity Loop
2             Name2           2 Infinity Loop
3             Name3           3 Infinity Loop

我的下一个表格名为[Group]
GroupID       GroupName
-------       ---------
1             Group1
2             Group2
3             Group3

然后,为了将这两个联系起来,我有一个名为[GroupCustomer]的表。
GroupID    CustomerID
-------    ----------
1          2
1          3
2          1
3          1

在ASP.NET页面上,我有两个表格需要显示。第一个表格基本上是特定组中的所有客户。因此,在下拉列表中,如果我选择Group1,它将显示以下表格:
CustomerID    CustomerName    CustomerAddress
----------    ------------    ---------------
2             Name2           2 Infinity Loop
3             Name3           3 Infinity Loop

上面的表格是针对与所选组(本例中为Group1)“关联”的所有客户端的。然后,在另一个表格中,我希望它显示如下内容:
CustomerID    CustomerName    CustomerAddress
----------    ------------    ---------------
1             Name1           1 Infinity Loop

基本上,对于这个表格,我希望它显示所有不在所选组中的客户。
为了生成所选组中所有客户的表格,我编写了以下 SQL 代码:
SELECT Customer.CustomerID, Customer.CustomerName, Customer.CustomerAddress   
FROM Customer
INNER JOIN GroupCustomer ON
    Customer.CustomerID = GroupCustomer.CustomerID
INNER JOIN [Group] ON
    GroupCustomer.GroupID = [Group].GroupID
WHERE [Group].GroupID = @selectedGroupParameter

当我提到我的n^2算法时,我基本上使用了上面的SQL语句,并将其与仅从“Customer”表中SELECT *的SQL语句进行了比较。如果有匹配项,我只是简单地让它不显示。这非常低效,而且我也不为此感到自豪。

这引出了我目前的问题,我可以编写什么最有效的SQL语句来消除我的n^2?

2个回答

2
你可以使用 NOT EXISTS 来获取不在特定 Group 中的 Customer:
SELECT *
FROM Customer c
WHERE
    NOT EXISTS(
        SELECT 1
        FROM GroupCustomer
        WHERE
            CustomerID = c.CustomerID
            AND GroupID = @selectedGroupParameter
    )

阅读Aaron Bertrand的文章,了解解决这种问题的不同方法以及它们的性能比较,根据他的测试,NOT EXISTS是最快的方法。

SQL Fiddle


不确定你的意思是 where c.CustomerID = c.CustomerID - APH
非常感谢您的帮助,以及Bertrand的文章! - Leon
没问题,很高兴能帮忙。你总是可以依靠Aaron在所有与SQL Server相关的问题上有答案。=) - Felix Pamittan

1
Select * from Customer
where CustomerID not in
  (select CustomerID 
  from GroupCustomer 
  where GroupID = @selectedGroupParameter)

您可以使用not in来进行此检查。也就是说,为了提高性能,您可能可以将Group表的连接去掉,因为您似乎没有实际使用组名。

1
谢谢你向我展示了“not in”。我会记住的。 :-) - Leon

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接