3

有什么方法可以避免内部连接以从客户表中获取客户名字和姓氏,以及如何优化执行计划?

SELECT c1.firstname, c1.lastname, t.*
FROM customer c1
INNER JOIN
    (select c.Customerid ,count(si.CustomerID) as 'No Of Orders'
    from Customer c
    LEFT OUTER join SalesInvoice si ON si.CustomerID = c.CustomerID
    GROUP by c.CustomerID) as t
ON c1.CustomerID = t.Customerid

在此处输入图像描述

4

3 回答 3

2

可能有两种方法可以做到这一点。一种方法是将所有非聚合列包含到分组列表中,如下所示:

SELECT
    c.firstname,
    c.lastname,
    c.CustomerId,
    count(si.CustomerID) as 'No Of Orders'
FROM
    customer c
LEFT OUTER JOIN
    SalesInvoice si ON si.CustomerID = c.CustomerID
GROUP BY
    c.CustomerID,
    c.firstname,
    c.lastname

另一种方法是在选择列表中使用聚合函数(应该使用最小值或最大值):

SELECT
    MIN(c.firstname) as firstname,
    MIN(c.lastname) as lastname,
    c.CustomerId,
    count(si.CustomerID) as 'No Of Orders'
FROM
    customer c
LEFT OUTER JOIN
    SalesInvoice si ON si.CustomerID = c.CustomerID
GROUP BY
    c.CustomerID

我认为第一个查询的性能可能更好。为了提高整体性能,您需要创建一个包含或覆盖索引。

您可以查看以下链接,了解包含的索引:

  1. 为什么在创建索引时使用 INCLUDE 子句?
  2. http://msdn.microsoft.com/en-IN/library/ms190806.aspx
于 2013-03-25T08:23:38.220 回答
1

使用OVER()子句尝试此选项

SELECT c1.Customerid, c1.firstname, c1.lastname, 
       COUNT(si.CustomerID) OVER(PARTITION BY c1.CustomerID) AS 'No Of Orders'
FROM customer c1 LEFT JOIN SalesInvoice si ON si.CustomerID = c1.CustomerID

为了提高性能,您需要此索引

CREATE INDEX ix_Customerid_Customer ON Customer(Customerid) INCLUDE(firstname, lastname)
于 2013-03-25T08:21:19.807 回答
0

试试那个:

SELECT
    c.firstname,
    c.lastname,
    c.CustomerId,
    count(si.CustomerID) as 'No Of Orders'
FROM
    customer c
LEFT OUTER JOIN
    SalesInvoice si ON si.CustomerID = c.CustomerID
GROUP BY
    c.CustomerID,
    c.firstname,
    c.lastname
于 2013-03-25T08:11:36.737 回答