2014-03-05 77 views
0

我已經閱讀了很多關於該主題的文章,但是我無法讓它適用於我的案例。T-SQL左連接1行(limi,subselect)

我有以下情況:

  • 的OrderItems(我想主要的數據集)
  • 文章其中有1清單:1關係的訂單項目
  • A N: m可加入的「Articlesupplier」,創建物品和 合作伙伴之間的關係
  • 合作伙伴表格,包含有關合作夥伴的詳細信息。

目標:
每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」。

問題是文章別名與表名具有相同的名稱嗎?

非常感謝提前對可能的想法, 邁克

+3

這是一個非常不幸的是,糟糕的命名約定打電話給你的表'IDX _......' - 這將直觀地指一個** **指標 - 不是表! –

+0

你是對的,但不幸的是,這不是我的數據庫,ERP系統的名稱是「IDX」,這就是這種命名約定的原因。 – Michael

回答

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 
+0

+1。 。 。謝謝。現在我不必去寫它。 –

+0

太棒了! OUTER APPLY解決了問題!非常感謝Lamak! – Michael

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被引用以相同的方式,我們引用相關子查詢中的外部查詢字段。

0

我看到兩個問題。

根據您的DDL,您沒有在左連接子句中引用的IDX_ARTICLE.supplier_partner_id。

其次,我很確定你不能在派生表中使用IDX_ARTICLE.id。只需將IDX_ARTICLESUPPLIER.article_id添加到您的派生表選定字段,並將其用於IDX_ARTICLE.id的左連接子句中。

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; 

接下來,我重寫了第一個查詢使用,而不是使用TOP (1)使用ROW_NUMBER您可以控制結果,你想,你不想要的東西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; 
+0

謝謝弗拉基米爾! – Michael

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