首页 > 解决方案 > 根据发票项目退回发票(INNER JOIN)

问题描述

我在 SQL Server 中有 2 个表:Invoice 和 InvoiceItem。两个表都有一个 InvoiceID 列,InvoiceItem 表有一个 ItemID 列。

我需要的是一个查询,如果 InvoiceItems 完全指定了 ItemID,我可以运行该查询以返回发票。

例子:

Invoice.InvoiceID = 1

InvoiceItem.InvoiceItemID = 1
InvoiceItem.InvoiceID = 1
InvoiceItem.ItemID = 1

InvoiceItem.InvoiceItemID = 2
InvoiceItem.InvoiceID = 1
InvoiceItem.ItemID = 2

我需要查询任何包含 2 个行项目的发票,一个项目 ID 为 1,一个项目 ID 为 2。

我认为带有“IN”语句的 INNER JOIN 可能会让我到达那里,但它返回的不仅仅是一张发票。以下返回任何 ItemID 为 1 或 2 的发票。这有点像我想要“IN”中的“and”而不是“or”。

SELECT InvoiceID FROM Invoice i INNER JOIN InvoiceItem ii ON i.InvoiceID = ii.InvoiceID WHERE ii.ItemID IN (1, 2)

标签: tsql

解决方案


而不是 OR 在 IN

我理解你的意思,但它不起作用,因为你正在考虑多行,这些行就像同一种项目的不同实例。如果您正在寻找 itemid = 1 和 itemid = 2 的行,您将永远得不到任何东西,因为没有单行满足这一点

相反,您可以查看特定发票的整个行集合,然后汇总查看它们。您实际上要说的是“我想要详细信息行数为 2 的发票 ID,最低项目 ID 为 1,最高项目 ID 为 2” - 这是“查看多行”并选择聚合属性:

SELECT InvoiceID 
FROM InvoiceItems 
GROUP BY InvoiceID 
HAVING 
  COUNT(*) = 2 AND 
  MIN(ItemId) = 1 AND 
  MAX(ItemID) = 2

笔记:

  • 如果 InvoiceID,ItemID 是唯一的,您可以省略计数检查
  • 如果您想从中获取信息,请将其放入子查询并随后加入 Invoices 表

您要求提供任意数量的项目,这是一种技术:

SELECT InvoiceID 
FROM InvoiceItems 
GROUP BY InvoiceID 
HAVING 
  SUM(CASE ItemID 
    WHEN 9 THEN 2 
    WHEN 38 THEN 4 
    WHEN 483 THEN 8 
    ELSE 1 END
  ) = 14 AND 
  COUNT(*) = 3

通过将您的数字转换为 2,4 或 8 并强制要求 3 项,只有一种方法可以达到 14..


推荐阅读