【问题标题】:Include subselect only if there is one result using tsql仅当使用 tsql 有一个结果时才包含子选择
【发布时间】:2010-11-05 15:16:13
【问题描述】:

我们有一张发票、一张发票明细和一个订单表,这些表格由发票明细行链接,因为发票明细按交货日期分组,因此一张发票通常包含多个订单号。

现在我想使用某种子选择构建一个视图,如果发票中只涉及一个订单,则该视图将显示订单号。

我想出了这个,但它仍然会生成一个错误报告,即子查询返回多个结果

SELECT Invoice.Id, Invoice.TotalAmount, 
(SELECT DISTINCT OrderId  FROM InvoiceDetail 
WHERE InvoiceDetail.InvoiceId = Invoice.Id
GROUP BY OrderId HAVING COUNT(DISTICT OrderId) = 1) AS OrderId 
FROM Invoice

有什么想法可以让它发挥作用吗?

【问题讨论】:

    标签: sql-server tsql subquery


    【解决方案1】:

    怎么样:

    SELECT 
      Invoice.Id,
      Invoice.TotalAmount,
      OneOrder.OrderId
    FROM 
      Invoice
      LEFT JOIN (
        SELECT   InvoiceId, MIN(OrderId) OrderId
        FROM     InvoiceDetail 
        GROUP BY InvoiceId
        HAVING   COUNT(DISTINCT OrderId) = 1
      ) OneOrder ON OneOrder.InvoiceId = Invoice.Id
    

    【讨论】:

    • 将 OrderId 放在一个聚合中是可行的,因为 orderid 可以在分组子句中省略。使用左外连接使其包含所有具有空值的发票,用于开具多个订单的发票。
    【解决方案2】:

    测试正确:

    SELECT Id, TotalAmount, OrderInfo.OrderId 
      FROM Invoice 
      JOIN
        (
          SELECT InvoiceId, OrderId 
            FROM InvoiceDetail 
            JOIN Invoice  
              ON InvoiceDetail.InvoiceId = Invoice.Id  
           GROUP BY InvoiceId, OrderId
          HAVING COUNT(OrderId)=1
        ) AS OrderInfo
        ON Invoice.Id=OrderInfo.InvoiceId
    

    请注意 HAVING 子句中缺少 DISTINCT,这是不正确的(这会导致多个订单 id 计为一个,破坏预期行为)

    【讨论】:

    • 修正原代码中的错字:DISTICT 应该是DISTINCT
    • GROUP BY InvoiceId, OrderId 保证履行HAVING COUNT(OrderId)=1 - 但这不是 OP 所要求的,恕我直言。
    • 如果发票有多个相关订单,此查询将返回具有相同发票编号的多张发票。目标是获取所有发票,但只有订单号有一个相关订单
    • @jhoefnagels:没错,它会返回多行,但都具有相同的 OrderId。如果我理解正确,可以有 N 个带有 InvoiceId 的 OrderId,他只会对只有一个 OrderId 的那些感兴趣。如果您按 OrderId 分组,我不知道您会如何发现这一点?
    • 就像我说的那样,我确实在各种场景下对此进行了测试,并且它对它们的行为是正确的(包括 0、1、>1 个具有特定发票 ID 的相同订单 ID 的订单)。如果有人能想到它不起作用的场景,我很乐意检查并修改查询。
    【解决方案3】:

    改变 GROUP BY OrderIdGROUP BY InvoiceDetail.InvoiceId

    【讨论】:

      【解决方案4】:

      您的问题可能只是HAVING 子句中的拼写错误。请参阅 DISTICT。

      【讨论】:

        猜你喜欢
        • 2013-08-09
        • 2011-04-20
        • 1970-01-01
        • 2014-02-22
        • 2011-12-17
        • 1970-01-01
        • 2022-01-19
        • 2011-12-11
        • 1970-01-01
        相关资源
        最近更新 更多