結合された結果がトリックでカンマ区切りのリストに連結されるwithDISTINCT
を使用して、真のレコードのセットを戻すのに問題があります。ROW_NUMBER()
LEFT JOIN
FOR XML PATH
目的は、Web アプリケーションにページングを実装することです。これは、返される可能性のあるレコードが多数あり、選択されたページ番号に応じて毎回サブセットのみが返されるためです。
次の SQL を検討してください。
SELECT DISTINCT IndustryCode,
STUFF (
(SELECT ',' + FE_LocationCode
FROM tblLegacy_Codes i2
WHERE c.IndustryCode = i2.IndustryCode
FOR XML PATH(''))
,1,1,'') AS LegacyList
FROM Common_Clli c
LEFT JOIN tblLegacy_Codes legacy ON c.IndustryCode = legacy.IndustryCode
WHERE FE_LocationCode LIKE 'AUS%'
予想どおり、非常に優れたDISTINCT
リストが返されます。
IndustryCode LegacyList
AUSTTX85 AUST.GET,AUST.LDD,AUST.UU4
AUSTTXTE AUST.TE,AUST.TEH
AUSUTX78 AUST.AX3
SCHWAS01 AUSC01C1,AUSC01UT
SZBGASAH AUSB01C1,AUSB01OB,AUSB01TA
SZBGASAI AUSB01SN,AUVI01SN,AUVI02SN
SZBGASAK AUSB03C1,AUSB03V1
BUT - 上記のクエリの最初の行に ROW_NUMBER 構文を追加すると、次のようになります。
SELECT DISTINCT ROW_NUMBER() OVER(ORDER BY IndustryCode) AS rowNum, IndustryCode,...
結果には、LegacyList に含まれているため、IndustryCode ごとに 1 行がDISTINCT
含まれるようになりました。結果セット全体を含めずに、3 つの子レコードが関連付けられているため、リスト内の最初の IndustryCode についてのみ表示されるものを次に示します。
rowNum IndustryCode LegacyList
1 AUSTTX85 AUST.GET,AUST.LDD,AUST.UU4
2 AUSTTX85 AUST.GET,AUST.LDD,AUST.UU4
3 AUSTTX85 AUST.GET,AUST.LDD,AUST.UU4
そしてもちろん、ページングの最終的な実装は、言及されたすべてのSQLをラップできるようにすることです
SELECT * FROM (
[ the SQL you've already seen ]
WHERE rowNum BETWEEN x and y
現時点では、最初に ROW_NUMBER() を使用せずに SQL を実行し、結果を一時テーブルに入れ、そこから最終製品を取得することに頼らなければなりませんでした。残念ながら、毎回レコードのサブセットのみを取得することで負荷を最小限に抑えるという意図が完全に無効になりました。
私が知らない何かがあるだけだとかなり確信しています。それは常に安全な賭けです。助けてくれてありがとう。
すべての要件を満たす最終製品は、以下の SQL になります。提供された最初の 2 つの解決策はどちらも役に立ちましたが、テーブルが共通テーブル式であるか他のものであるかに関係なく、最初にクエリの結果全体を一時的なスタイル テーブルに格納する必要はありませんでした。このStackOverflow スレッドは、私を完全な解決に導きました。
SELECT RowNum, IndustryCode, FEList FROM
(
SELECT ROW_NUMBER() OVER(ORDER BY IndustryCode) AS RowNum, IndustryCode, FEList
FROM
(
SELECT DISTINCT IndustryCode,
STUFF (
(SELECT ',' + FE_LocationCode
FROM tblLegacyCodes i2
WHERE c.IndustryCode = i2.IndustryCode
FOR XML PATH(''))
,1,1,'') AS LegacyList
FROM Common_Clli c
LEFT JOIN tblLegacyCodes legacy ON c.IndustryCode = legacy.IndustryCode
WHERE FE_LocationCode LIKE 'AUS%'
) subInner
) subOuter
WHERE RowNum BETWEEN x AND y