我已经在该主题上阅读了很多内容,但我无法让它适用于我的案例。
我有以下情况:
目标:
每个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别名与表名具有相同名称的问题是什么?
非常感谢您提出可能的想法, 麦克
答案 0 :(得分:2)
好吧,我更改了你的别名,以及你加入的子查询(我也修改了那个子查询,所以它不再使用隐式连接),虽然这改变了主要是化妆品的地方。实际的重要更改是使用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
答案 1 :(得分:0)
因为下面的查询
而引发错误 (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
的方式与我们在相关子查询中引用外部查询字段的方式相同。
答案 2 :(得分:0)
我看到两个问题。
根据您的DDL,没有IDX_ARTICLE.supplier_partner_id,您在左连接条款中引用它。
其次,我很确定你不能在派生表中使用IDX_ARTICLE.id。只需将IDX_ARTICLESUPPLIER.article_id添加到派生表中的选定字段,并在针对IDX_ARTICLE.id的左连接on子句中使用它。
答案 3 :(得分:0)
我更喜欢避免嵌套查询。如果可以,我将始终使用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;
答案 4 :(得分:0)
谢谢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