[英]T-SQL Left-Join with 1 row (limi, subselect)
我已经阅读了很多关于该主题但我无法让它适用于我的案例。
我有以下情况:
目标:
每个OrderItem和供应商的一个数据集我只想获得在连接中找到的第一个数据集。 无需优先处理。
表:
表IDX_ORDERITEM
id,article_id
表IDX_ARTICLE
id,name
表IDX_ARTICLESUPPLIER
article_id,partner_id
表IDX_PARTNER
id,abbr
我的实际陈述(简短版):
SELECT IDX_ORDERITEM.id
FROM
dbo.IDX_ORDERITEM AS IDX_ORDERITEM
-- ARTICLE --
INNER JOIN dbo.IDX_ARTICLE AS IDX_ARTICLE
ON IDX_ORDERITEM.article_id=IDX_ARTICLE.id
-- SUPPLIER VIA ARTICLE --
LEFT JOIN
(SELECT TOP(1) IDX_PARTNER.id, IDX_PARTNER.abbr
FROM IDX_PARTNER, IDX_ARTICLESUPPLIER
WHERE IDX_PARTNER.id = IDX_ARTICLESUPPLIER.partner_id
AND IDX_ARTICLESUPPLIER.article_id=IDX_ARTICLE.id) AS IDX_PARTNER_SUPPLIER
ON IDX_PARTNER_SUPPLIER.id=IDX_ARTICLE.supplier_partner_id
WHERE 1>0
ORDER BY orderitem.id DESC
但似乎我无法访问子查询中的IDX_ARTICLE.id。 我收到以下错误消息:
无法绑定多部分标识符“IDX_ARTICLE.id”。
Article别名与表名具有相同名称的问题是什么?
迈克,非常感谢您提出可能的想法
好吧,我更改了你的别名,以及你加入的子查询(我也修改了那个子查询,所以它不再使用隐式连接),尽管这改变了主要是化妆品的地方。 实际的重要变化是使用OUTER APPLY
而不是LEFT JOIN
:
SELECT OI.id
FROM dbo.IDX_ORDERITEM AS OI
INNER JOIN dbo.IDX_ARTICLE AS A
ON OI.article_id = A.id
OUTER APPLY
(SELECT TOP(1) P.id, P.abbr
FROM IDX_PARTNER AS P
INNER JOIN IDX_ARTICLESUPPLIER AS SUP
ON P.id = SUP.partner_id
WHERE SUP.article_id = A.id
AND P.id = A.supplier_partner_id) AS PS
ORDER BY OI.id DESC
抛出错误是因为下面的查询
(SELECT TOP(1) IDX_PARTNER.id, IDX_PARTNER.abbr
FROM IDX_PARTNER, IDX_ARTICLESUPPLIER
WHERE IDX_PARTNER.id = IDX_ARTICLESUPPLIER.partner_id
AND IDX_ARTICLESUPPLIER.article_id=IDX_ARTICLE.id) AS IDX_PARTNER_SUPPLIER
不能将其视为相关子查询, IDX_ARTICLE.id
在其中引用的方式与我们在相关子查询中引用外部查询字段的方式相同。
我看到两个问题。
根据您的DDL,没有IDX_ARTICLE.supplier_partner_id,您在左连接on子句中引用它。
其次,我很确定你不能在派生表中使用IDX_ARTICLE.id。 只需将IDX_ARTICLESUPPLIER.article_id添加到派生表中的选定字段,并在针对IDX_ARTICLE.id的左连接on子句中使用它。
我更喜欢避免嵌套查询。 如果可以,我将始终使用CTE重写它。
WITH Part_Sup
AS (
SELECT TOP ( 1 ) P.id
,P.abbr
,SUP.article_id
FROM IDX_PARTNER AS P
INNER JOIN IDX_ARTICLESUPPLIER AS SUP
ON P.id = SUP.partner_id
)
SELECT OI.id
FROM dbo.IDX_ORDERITEM AS OI
INNER JOIN dbo.IDX_ARTICLE AS A
ON OI.article_id = A.id
LEFT OUTER JOIN Part_Sup AS PS
ON PS.article_id = A.Id
AND PS.id = A.supplier_partner_id
ORDER BY OI.id DESC;
接下来,我重写了第一个查询以使用ROW_NUMBER()
函数而不是使用TOP (1)
使用ROW_NUMBER
您可以控制您想要的结果和您不想要的结果。
WITH Part_Sup
AS (
SELECT P.id
,P.abbr
,SUP.article_id
,ROW_NUMBER() OVER ( PARTITION BY P.id, P.abbr ) AS RowNum
FROM IDX_PARTNER AS P
INNER JOIN IDX_ARTICLESUPPLIER AS SUP
ON P.id = SUP.partner_id
)
SELECT OI.id
FROM dbo.IDX_ORDERITEM AS OI
INNER JOIN dbo.IDX_ARTICLE AS A
ON OI.article_id = A.id
LEFT OUTER JOIN Part_Sup AS PS
ON PS.article_id = A.Id
AND PS.id = A.supplier_partner_id
AND RowNum = 1
ORDER BY OI.id DESC;
谢谢Lamak - 你解决了它:)我使用你的输入提取基本解决方案,使其更容易阅读其他有相同问题的人:
使用OUTER APPLY(此处没有ORDER_ITEM表):
SELECT IDX_ARTICLE.id AS AR_ID, IDX_PARTNER_SUPPLIER.id, IDX_PARTNER_SUPPLIER.abbr
FROM
dbo.IDX_ARTICLE AS IDX_ARTICLE
OUTER APPLY
(SELECT TOP(1) _PARTNER.id, _PARTNER.abbr
FROM IDX_PARTNER AS _PARTNER
INNER JOIN IDX_ARTICLESUPPLIER AS _ARTICLESUPPLIER
ON _PARTNER.id = _ARTICLESUPPLIER.partner_id
WHERE _ARTICLESUPPLIER.article_id=IDX_ARTICLE.id
AND _ARTICLESUPPLIER.deleted IS NULL) AS IDX_PARTNER_SUPPLIER
WHERE IDX_ARTICLE.id=67
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.