SQL Server查询自2017年以来未开具发票的2017年之前的主要客户

时间:2018-07-06 22:57:55

标签: sql sql-server subquery

我正在尝试编写查询以列出<2017年以来自2017年以来没有发票金额的前200名客户。

我尝试了几种查询变体,但始终提供0个结果,我知道默认情况下这是不准确的,但我在Excel中得到了正确的信息。我在子查询方面经验不足,因此看到了完成子查询的机会。

SELECT TOP 200
    SUM(OI.OrderInvoiceTotalAmount) AS 'Invoiced',
    O.Deal,
    CASE
       WHEN O.Location LIKE '%Vegas%' THEN 'Las Vegas'
        WHEN O.Location LIKE '%New%' THEN 'New Jersey'
        WHEN O.Location LIKE '%Orange%' THEN 'Los Angeles'
        WHEN O.Location LIKE '%Angeles%' THEN 'Los Angeles'
        WHEN O.Location LIKE '%Angeles%' AND O.OrderType = 'System' THEN 'Las Vegas'
        WHEN O.Location LIKE '%DC%' THEN 'Washington DC'
        WHEN O.Location LIKE '%DC%' AND O.OrderType = 'System' THEN 'New Jersey'
        WHEN O.Location LIKE '%Nashville%' THEN 'Tennessee'
        WHEN O.Location LIKE '%Nashville%' AND O.OrderType = 'System' THEN 'Las Vegas'
        WHEN O.Location LIKE '%Houston%' THEN 'Houston'
        WHEN O.Location LIKE '%Orlando%' THEN 'Orlando'
        WHEN O.Location LIKE 'Penn%' THEN 'Pennsylvania'
        WHEN O.Location='Enterprises' THEN 'Entertainment'
        ELSE O.Location
    END AS 'Location'
FROM 
    dbo.OrderInvoice as OI
INNER JOIN 
    dbo.Orders as O ON O.OrderKey = OI.OrderKey
INNER JOIN 
    dbo.Invoice as I on I.InvoiceKey = OI.InvoiceKey
WHERE 
    O.Status NOT IN ('Snapshot', 'Cancelled', 'Void')
    AND I.InvoiceStatusCode <> 'Estimate'
    AND I.InvoiceType = 'Billing'
    AND Year(I.InvoiceDate) < '2017'
    AND O.Deal NOT LIKE '%4Wall%'
    AND O.Location LIKE '%Nashville%'
GROUP BY
    O.Deal,
    CASE
        WHEN O.Location LIKE '%Vegas%' THEN 'Las Vegas'
        WHEN O.Location LIKE '%New%' THEN 'New Jersey'
        WHEN O.Location LIKE '%Orange%' THEN 'Los Angeles'
        WHEN O.Location LIKE '%Angeles%' THEN 'Los Angeles'
        WHEN O.Location LIKE '%Angeles%' AND O.OrderType = 'System' THEN 'Las Vegas'
        WHEN O.Location LIKE '%DC%' THEN 'Washington DC'
        WHEN O.Location LIKE '%DC%' AND O.OrderType = 'System' THEN 'New Jersey'
        WHEN O.Location LIKE '%Nashville%' THEN 'Tennessee'
        WHEN O.Location LIKE '%Nashville%' AND O.OrderType = 'System' THEN 'Las Vegas'
        WHEN O.Location LIKE '%Houston%' THEN 'Houston'
        WHEN O.Location LIKE '%Orlando%' THEN 'Orlando'
        WHEN O.Location LIKE 'Penn%' THEN 'Pennsylvania'
        WHEN O.Location = 'Enterprises' THEN 'Entertainment'
        ELSE O.Location
    END
HAVING
    (SELECT SUM(OI.OrderInvoiceTotalAmount)
     FROM dbo.OrderInvoice as OI
     INNER JOIN dbo.Invoice as I on OI.InvoiceKey=I.InvoiceKey
     INNER JOIN dbo.Orders as O on OI.OrderKey=O.OrderKey
     WHERE YEAR(I.InvoiceDate) > '2017' 
       AND I.InvoiceStatusCode <> 'Estimate'
       AND I.InvoiceType = 'Billing'
       AND O.Deal NOT LIKE '%4Wall%'
       AND O.Location LIKE '%Nashville%') = 0

让我知道是否需要添加更多信息。

感谢好人

1 个答案:

答案 0 :(得分:0)

检查缺少的行时,使用NOT EXISTS的速度要比实际执行COUNT并检查其是否为0快(引擎必须在比较之前对所有行进行计数)。我评论了我编辑的行。基本上删除了HAVING,并在NOT EXISTS上添加了WHERE

Select TOP 200
Sum(OI.OrderInvoiceTotalAmount) as 'Invoiced',
O.Deal,
Case
    When O.Location Like '%Vegas%' Then 'Las Vegas'
    When O.Location Like '%New%' Then 'New Jersey'
    When O.Location Like '%Orange%' Then 'Los Angeles'
    When O.Location Like '%Angeles%' Then 'Los Angeles'
    When O.Location Like '%Angeles%' AND O.OrderType='System' Then 'Las Vegas'
    When O.Location Like '%DC%' Then 'Washington DC'
    When O.Location Like '%DC%' AND O.OrderType='System' Then 'New Jersey'
    When O.Location Like '%Nashville%' Then 'Tennessee'
    When O.Location Like '%Nashville%' AND O.OrderType='System' Then 'Las Vegas'
    When O.Location Like '%Houston%' Then 'Houston'
    WHen O.Location Like '%Orlando%' Then 'Orlando'
    When O.Location Like 'Penn%' Then 'Pennsylvania'
    When O.Location='Enterprises' Then 'Entertainment'
    Else O.Location
End as 'Location'

From dbo.OrderInvoice as OI
Inner Join dbo.Orders as O on O.OrderKey=OI.OrderKey
Inner Join dbo.Invoice as I on I.InvoiceKey=OI.InvoiceKey

Where O.Status Not In ('Snapshot','Cancelled','Void')
AND I.InvoiceStatusCode<>'Estimate'
AND I.InvoiceType='Billing'
AND Year(I.InvoiceDate)<'2017'
AND O.Deal Not Like '%4Wall%'
AND O.Location Like '%Nashville%'

-- no record from 2017 must exist
AND NOT EXISTS (
    SELECT 
        'no record from 2017'
    From dbo.OrderInvoice as XOI -- Note that we use different alias here so it doesn't get mixed up
    Inner Join dbo.Invoice as XI on XOI.InvoiceKey=XI.InvoiceKey
    Inner Join dbo.Orders as XO on XOI.OrderKey=XO.OrderKey
    Where Year(XI.InvoiceDate)> 2017
        AND XI.InvoiceStatusCode<>'Estimate'
        AND XI.InvoiceType='Billing'
        AND XO.Deal Not Like '%4Wall%'
        AND XO.Location Like '%Nashville%'

        AND O.Deal = XO.Deal -- link between the outmost query and the correlated query
    )

Group By
O.Deal,
Case
    When O.Location Like '%Vegas%' Then 'Las Vegas'
    When O.Location Like '%New%' Then 'New Jersey'
    When O.Location Like '%Orange%' Then 'Los Angeles'
    When O.Location Like '%Angeles%' Then 'Los Angeles'
    When O.Location Like '%Angeles%' AND O.OrderType='System' Then 'Las Vegas'
    When O.Location Like '%DC%' Then 'Washington DC'
    When O.Location Like '%DC%' AND O.OrderType='System' Then 'New Jersey'
    When O.Location Like '%Nashville%' Then 'Tennessee'
    When O.Location Like '%Nashville%' AND O.OrderType='System' Then 'Las Vegas'
    When O.Location Like '%Houston%' Then 'Houston'
    WHen O.Location Like '%Orlando%' Then 'Orlando'
    When O.Location Like 'Penn%' Then 'Pennsylvania'
    When O.Location='Enterprises' Then 'Entertainment'
    Else O.Location
End

我假设相关查询的链接通过Deal列。