首页 > 解决方案 > 在多个表中使用多个相互依赖的 CROSS-APPLY

问题描述

如何根据其他表中的值使用CROSS APPLY(或INNER JOIN)从一个表中获取数据?

即我有以下表格:

表说明:

产品编号 描述 曲目编号
361 测试 1 499
388 测试 2 003
004 5599
238 测试 3 499
361 测试 10 555
004 测试 40 555

表产品:

产品编号 产品名称 价格
361 P1 5.00
388 P2 5.00
004 P3 12.00
238 P4 6.00
515 P5 7.00
636 P6 7.00
775 P7 7.00
858 P8 8.00

表发票:

产品编号 曲目编号 发票编号
361 499 718
388 199 718
004 499 718
238 499 718
361 555 333
004 555 444
361 111 444
388 222 333
616 116 565
717 116 565
361 003 221
388 003 221
004 5599 728

我需要我的查询做的是:

  1. 先进入 Invoices 表,只获取与指定 InvoiceID 和 TrackNum 匹配的记录;
  2. 然后进入 Products 表,获取在步骤#1 中提取的数据与 Products 表中存在的数据之间的ProdID匹配的行。
  3. 然后最后从 Descriptions 表中获取所有列,但仅针对我在步骤 #2 中获得并且与 ProdID 匹配的行。

最后我需要的是这样的(如果我得到更多的列,那很好,但我不想得到更多的行):

产品编号 描述 曲目编号
361 测试 1 499
004 5599
238 测试 3 499

我有以下查询(并且我尝试过使用INNER JOINand CROSS APPLY) - 但它返回的行数比我需要的多:

SELECT * FROM [Descriptions] AS [DES] 
CROSS APPLY
(
    select * from [Invoices] AS [INV] where [INV].[TrackNum] = '499' AND [INV].[InvoiceID] = '718'
) [INV]
CROSS APPLY 
    (
        select * from [Products] AS [GP] 
        WHERE [GP].[ProdID] = [INV].[ProdID]
    ) [GP2]
WHERE 
[DES].[ProdID] = [GP2].[ProdID]
order by [DES].[ProdID] asc

标签: sqlsql-serverperformanceinner-joincross-apply

解决方案


SELECT
  *
FROM
  invoices   AS i
LEFT JOIN
  descriptions   AS d
    ON  d.prodid = i.prodid
    AND d.tracknum = i.tracknum -- you don't have this, but I think it's required.
LEFT JOIN
  products   AS p
    ON  p.prodid = i.prodid
WHERE
      i.invoiceid = 718
  AND i.tracknum = 499
ORDER BY
  i.prodid

我担心的一件事是发票和描述都有一个名为的列tracknum,但是您的查询和预期数据表明您不想将其包含在联接中?这非常令人困惑,要么是一个糟糕的列名,要么是您的查询和示例结果中的错误。


推荐阅读