跨多个表使用多个相互依赖的 CROSS-APPLY
Using multiple and interdepended CROSS-APPLY across multiple tables
如何使用 CROSS APPLY
(或 INNER JOIN
)根据其他 table 中的值从一个 table 获取数据?
即我有以下 tables:
Table 说明:
ProdID
Description
TrackNum
361
Test 1
499
388
Test 2
003
004
5599
238
Test 3
499
361
Test 10
555
004
Test 40
555
Table 产品:
ProdID
ProductName
Price
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
Table 发票:
ProdID
TrackNum
InvoiceID
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
我需要查询的是:
- 首先进入 Invoices table,只获取与指定的 InvoiceID 和 TrackNum 匹配的记录;
- 然后进入产品 table 并获得 仅 行 匹配 ProdID 在我在步骤 #1 中提取的数据和产品中存在的数据之间 table。
- 然后最终从描述 table 中获取所有列,但仅限于我在步骤 #2 中获取并与 ProdID 匹配的行。
我最后需要的是这样的(如果我得到更多的列那很好,但我不想得到更多的行):
ProdID
Description
TrackNum
361
Test 1
499
004
5599
238
Test 3
499
我有以下查询(并且我尝试使用 INNER JOIN
和 CROSS APPLY
)- 但它 returns 我的行比我需要的多:
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
table 和一个 where 子句开始以获得正确的行,然后加入 Products
和 Descriptions
.
我也猜你想在 TrackNum
上匹配 Description
?因为看起来你有一个独特的 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' 来查询您想要在主 table.
中每行 run/evaluate 的查询
在这种情况下,Inner Join 就足够了。您不需要使用交叉应用
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
的列,但您的查询和预期数据表明您不想要将其包含在连接中?这非常令人困惑,或者列名不正确,或者查询和示例结果中有错误。
如何使用 CROSS APPLY
(或 INNER JOIN
)根据其他 table 中的值从一个 table 获取数据?
即我有以下 tables:
Table 说明:
ProdID | Description | TrackNum |
---|---|---|
361 | Test 1 | 499 |
388 | Test 2 | 003 |
004 | 5599 | |
238 | Test 3 | 499 |
361 | Test 10 | 555 |
004 | Test 40 | 555 |
Table 产品:
ProdID | ProductName | Price |
---|---|---|
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 |
Table 发票:
ProdID | TrackNum | InvoiceID |
---|---|---|
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 |
我需要查询的是:
- 首先进入 Invoices table,只获取与指定的 InvoiceID 和 TrackNum 匹配的记录;
- 然后进入产品 table 并获得 仅 行 匹配 ProdID 在我在步骤 #1 中提取的数据和产品中存在的数据之间 table。
- 然后最终从描述 table 中获取所有列,但仅限于我在步骤 #2 中获取并与 ProdID 匹配的行。
我最后需要的是这样的(如果我得到更多的列那很好,但我不想得到更多的行):
ProdID | Description | TrackNum |
---|---|---|
361 | Test 1 | 499 |
004 | 5599 | |
238 | Test 3 | 499 |
我有以下查询(并且我尝试使用 INNER JOIN
和 CROSS APPLY
)- 但它 returns 我的行比我需要的多:
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
table 和一个 where 子句开始以获得正确的行,然后加入 Products
和 Descriptions
.
我也猜你想在 TrackNum
上匹配 Description
?因为看起来你有一个独特的 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' 来查询您想要在主 table.
中每行 run/evaluate 的查询在这种情况下,Inner Join 就足够了。您不需要使用交叉应用
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
的列,但您的查询和预期数据表明您不想要将其包含在连接中?这非常令人困惑,或者列名不正确,或者查询和示例结果中有错误。