2つのテーブルがあります。
TableA
------
ID,
Name
TableB
------
ID,
SomeColumn,
TableA_ID (FK for TableA)
関係は、TableA
の1行-TableB
の多くです。
今、私はこのような結果を見たいです:
ID Name SomeColumn
1. ABC X, Y, Z (these are three different rows)
2. MNO R, S
これは機能しません(サブクエリの複数の結果):
SELECT ID,
Name,
(SELECT SomeColumn FROM TableB WHERE F_ID=TableA.ID)
FROM TableA
クライアント側で処理を行う場合、これは些細な問題です。しかし、これはすべてのページでXクエリを実行する必要があることを意味します。XはTableA
の結果の数です。
TableA
の行に対して複数の結果を返すため、単にGROUP BYなどを実行することはできません。
COALESCEなどを利用したUDFが機能するかどうかわかりませんか?
CREATE FUNCTION CombineValues
(
@FK_ID INT -- The foreign key from TableA which is used
-- to fetch corresponding records
)
RETURNS VARCHAR(8000)
AS
BEGIN
DECLARE @SomeColumnList VARCHAR(8000);
SELECT @SomeColumnList =
COALESCE(@SomeColumnList + ', ', '') + CAST(SomeColumn AS varchar(20))
FROM TableB C
WHERE C.FK_ID = @FK_ID;
RETURN
(
SELECT @SomeColumnList
)
END
SELECT ID, Name, dbo.CombineValues(FK_ID) FROM TableA
CREATE PROCEDURE GetCombinedValues
@FK_ID int
As
BEGIN
DECLARE @SomeColumnList VARCHAR(800)
SELECT @SomeColumnList =
COALESCE(@SomeColumnList + ', ', '') + CAST(SomeColumn AS varchar(20))
FROM TableB
WHERE FK_ID = @FK_ID
Select *, @SomeColumnList as SelectedIds
FROM
TableA
WHERE
FK_ID = @FK_ID
END
これでも目的を果たす
サンプルデータ
declare @t table(id int, name varchar(20),somecolumn varchar(MAX))
insert into @t
select 1,'ABC','X' union all
select 1,'ABC','Y' union all
select 1,'ABC','Z' union all
select 2,'MNO','R' union all
select 2,'MNO','S'
クエリ:
SELECT ID,Name,
STUFF((SELECT ',' + CAST(T2.SomeColumn AS VARCHAR(MAX))
FROM @T T2 WHERE T1.id = T2.id AND T1.name = T2.name
FOR XML PATH('')),1,1,'') SOMECOLUMN
FROM @T T1
GROUP BY id,Name
出力:
ID Name SomeColumn
1 ABC X,Y,Z
2 MNO R,S
あなたはCOALESCEで正しい軌道に乗っていると思います。コンマ区切りの文字列を作成する例については、こちらをご覧ください。
http://www.sqlteam.com/article/using-coalesce-to-build-comma-delimited-string
MySQLには、あなたが求めているものを返す group_concat 関数があります。
SELECT TableA.ID, TableA.Name, group_concat(TableB.SomeColumn)
as SomColumnGroup FROM TableA LEFT JOIN TableB ON
TableB.TableA_ID = TableA.ID
テーブルAにWHERE句しかない場合、次のようにストアドプロシージャを作成します。
SELECT Id, Name From tableA WHERE ...
SELECT tableA.Id AS ParentId, Somecolumn
FROM tableA INNER JOIN tableB on TableA.Id = TableB.F_Id
WHERE ...
次に、DataSet dsにそれを入力します。それから
ds.Relations.Add("foo", ds.Tables[0].Columns("Id"), ds.Tables[1].Columns("ParentId"));
最後に、ページにリピーターを追加して、すべての行にコンマを入れることができます
<asp:DataList ID="Subcategories" DataKeyField="ParentCatId"
DataSource='<%# Container.DataItem.CreateChildView("foo") %>' RepeatColumns="1"
RepeatDirection="Horizontal" ItemStyle-HorizontalAlign="left" ItemStyle-VerticalAlign="top"
runat="server" >
このようにして、クライアント側でそれを行いますが、データベースとフロントエンド間で最小限のデータを渡すクエリを1つだけ使用します
Priyanka.sarkarが言及した解決策を試してみましたが、OPが尋ねたように、それがうまく機能しませんでした。ここに私が終わった解決策があります:
SELECT ID,
SUBSTRING((
SELECT ',' + T2.SomeColumn
FROM @T T2
WHERE WHERE T1.id = T2.id
FOR XML PATH('')), 2, 1000000)
FROM @T T1
GROUP BY ID
より正確な応答を得るには、詳細を提供する必要がある場合があります。
データセットが狭いように見えるため、結果ごとに行を使用し、クライアントで後処理を実行することを検討することができます。
したがって、サーバーに作業を行わせて、次のような結果セットを返すようにしたい場合
ID Name SomeColumn
1 ABC X
1 ABC Y
1 ABC Z
2 MNO R
2 MNO S
もちろん、これはIDの簡単な内部結合です
クライアントで結果セットを取得したら、CurrentNameという変数を維持し、SomeColumnの収集を目的の有用なものに停止するタイミングをトリガーとして使用します。