跨多个表使用多个相互依赖的 CROSS-APPLY

问题描述

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

我有以下表格:

表格说明:

产品ID 说明 TrackNum
361 测试 1 499
388 测试 2 003
004 5599
238 测试 3 499
361 测试 10 555
004 测试 40 555

餐桌产品:

产品ID 产品名称 价格
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

表格发票:

产品ID TrackNum 发票ID
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 中提取的数据和在 ProdID 上具有匹配的行数据存在于 Products 表中。
  3. 然后最终从 Descriptions 表中获取所有列,但仅限于我在第 2 步中获取且与 ProdID 匹配的行。

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

产品ID 说明 TrackNum
361 测试 1 499
004 5599
238 测试 3 499

我有以下查询(我曾尝试使用 INNER JOINCROSS 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

解决方法

根据您的描述,您需要以下内容,从您的 Invoices 表和 where 子句开始以获得正确的行,然后在 ProductsDescriptions 上加入。

我猜您还想匹配 Description 上的 TrackNum?因为看起来您对每个 Description/ProdId 组合都有一个唯一的 TrackNum

select [INV].[ProdID],[DES].[Description],[INV].[TrackNum]
from [Invoices] as [INV]
inner join [Products] as [GP] on [GP].[ProdID] = [INV].[ProdID]
inner join [Descriptions] on [DES].[ProdID] = [GP].[ProdID] and [DES].[TrackNum] = [INV].[TrackNum]
where [INV].[TrackNum] = '499' AND [INV].[InvoiceID] = '718'
order by [DES].[ProdID] asc;

注意:您通常只将“CROSS 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 的列,但您的查询和预期数据表明您不想希望将其包含在加入?这非常令人困惑,要么是一个糟糕的列名,要么是查询和示例结果中的错误。

,

在这种情况下,内连接就足够了。您不需要使用交叉应用

相关问答

Selenium Web驱动程序和Java。元素在(x,y)点处不可单击。其...
Python-如何使用点“。” 访问字典成员?
Java 字符串是不可变的。到底是什么意思?
Java中的“ final”关键字如何工作?(我仍然可以修改对象。...
“loop:”在Java代码中。这是什么,为什么要编译?
java.lang.ClassNotFoundException:sun.jdbc.odbc.JdbcOdbc...