2016-04-30 43 views
2

我有一個「主」表包含一個ID(加上一些其他列)和一個又名錶,它通過[main id]列連接到main.id.下面的查詢將返回主某些列與級聯逗號分隔的「姓氏」 S從又名柱沿:當連接列時,是否可以避免select中的子查詢?

SELECT m.id, m.name, 
    (SELECT a.[lastname] + ',' AS [text()] 
    FROM aka a 
    WHERE a.[main id] = m.[id] 
    FOR xml path ('')) [akas] 
FROM main m 

這工作得很好,但我想知道是否有避免做的方式這在一個子查詢?

+0

沒有使用子查詢,您可能仍然需要在最終選擇結果之前加入2個表。 –

+0

有什麼理由不能加入主要與aka?什麼是特殊的,所以你正在使用XML路徑? – FLICKER

+0

你可以創建你自己的CLR聚合,然後它將是一個普通的'group by',沒有子查詢。 –

回答

2

使用CROSS APPLY你可以從SELECT列表中移動的子查詢:

SELECT m.id, m.name, 
    (SELECT a.[lastname] + ',' AS [text()] 
    FROM aka a 
    WHERE a.[main id] = m.[id] 
    FOR xml path ('')) [akas] 
FROM main m; 

到:

SELECT m.id, m.name, s.akas 
FROM main m 
CROSS APPLY (SELECT a.[lastname] + ',' AS [text()] 
      FROM aka a 
      WHERE a.[main id] = m.[id] 
      FOR xml path ('')) AS s(akas) 

注:

  • 您可以參考s.akas多時間
  • 您可以添加在SELECT列表
  • 龍子查詢可能會少可讀
  • 如果possbile是相關子查詢回報,你需要使用OUTER APPLY,而不是任何行。
0

由於您有最終字符串組合的任意數量的記錄,因此您擁有的是SQL中執行此操作的最佳選擇。通常,您需要爲每個項目返回一行,並且如果您需要CSV字符串,請在您的客戶端代碼中構建該字符串。

1

一概而論沒有什麼反對在技術視圖一個子查詢...

你可能更喜歡APPLY由於可讀性或多參考。

每當你直接把一個子查詢到列的列表喜歡這裏:

SELECT Column1 
     ,Column2 
     ,(SELECT x FROM y) AS Column3 
     ,[...] 

...這個子選擇必須提供

  • 只是一列
  • 只是一個

使用FOR XML PATH(''),TYPE可以讓結果爲一個單值e XML。這使得可以返回許多行/列爲「一體」。沒有,TYPE這將是XML「作爲文本」。與XML的連接技巧是可能的,因爲XML的生成具有空標籤名稱的特性,並返回「as text」。但無論如何:返回的值將只是一個信息位,因此適合列列表。

每當你想到多行,你必須強迫這是一個數據位(如 - 經常看到! - SELECT TOP 1 x FROM y ORDER BY SomeSortKey,其中帶回第一個或最後一個或......)

所有其他意圖獲得1:n數據需要'JOIN'或'APPLY'。有了標量數據,就像你的情況一樣,不管你使用子選擇還是使用APPLY,實際上都沒有區別。