Kombinieren Sie mehrere Ergebnisse in einer Unterabfrage in einem einzigen komma-separierte
-
02-07-2019 - |
Frage
Ich habe zwei Tabellen:
TableA
------
ID,
Name
TableB
------
ID,
SomeColumn,
TableA_ID (FK for TableA)
Die Beziehung ist eine Reihe von TableA
- viele von TableB
Nun, ich möchte ein Ergebnis so sehen:
ID Name SomeColumn
1. ABC X, Y, Z (these are three different rows)
2. MNO R, S
Das wird nicht funktionieren (mehrere Ergebnisse in einer Unterabfrage):
SELECT ID,
Name,
(SELECT SomeColumn FROM TableB WHERE F_ID=TableA.ID)
FROM TableA
Dies ist ein triviales Problem, wenn ich die Verarbeitung auf der Client-Seite tun. Aber dies bedeutet, ich werde auf jeder Seite X Abfragen auszuführen haben, wobei X die Anzahl der Ergebnisse von TableA
ist.
Beachten Sie, dass ich nicht einfach eine GROUP BY oder etwas ähnliches tun, da es mehrere Ergebnisse für Reihen von TableA
zurück.
Ich bin mir nicht sicher, ob ein UDF, unter Verwendung von COALESCE oder etwas ähnlichem funktionieren könnte?
Lösung 2
1. Erstellen Sie die 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
2. Verwenden Sie in Unterabfrage:
SELECT ID, Name, dbo.CombineValues(FK_ID) FROM TableA
3. Wenn Sie gespeicherte Prozedur verwenden, können Sie wie folgt tun:
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
Andere Tipps
Auch wird dies den Zweck dienen
Beispieldaten
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'
Abfrage:
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
Ausgang:
ID Name SomeColumn
1 ABC X,Y,Z
2 MNO R,S
Ich glaube, Sie auf dem richtigen Weg mit COALESCE sind. Sehen Sie hier ein Beispiel für den Aufbau einer kommagetrennte Zeichenfolge:
http://www.sqlteam.com/ Artikel / using-coalesce-to-build-kommagetrennte-string
In MySQL gibt es einen Group_concat Funktion, die zurückkehren wird, was Sie fordern.
SELECT TableA.ID, TableA.Name, group_concat(TableB.SomeColumn)
as SomColumnGroup FROM TableA LEFT JOIN TableB ON
TableB.TableA_ID = TableA.ID
Sie müssen möglicherweise noch einige weitere Details für eine genauere Antwort liefern.
Da Dataset Art schmal scheint, sollten Sie überlegen, nur eine Zeile pro Ergebnis mit und die Nachbearbeitung auf dem Client ausgeführt wird.
Also, wenn Sie schauen, wirklich um den Server zu machen kehrt die Arbeit eine Ergebnismenge wie
ID Name SomeColumn
1 ABC X
1 ABC Y
1 ABC Z
2 MNO R
2 MNO S
was natürlich eine einfache INNER JOIN auf ID
Wenn Sie die Ergebnismenge zurück an den Client haben, halten eine Variable namens current und verwenden, die als Auslöser, wenn SomeColumn in die nützliche Sache zu stoppen Sammeln Sie es tun wollen.
Angenommen, Sie haben nur WHERE-Klauseln auf Tabelle A eine gespeicherte Prozedur erstellen also:
SELECT Id, Name From tableA WHERE ...
SELECT tableA.Id AS ParentId, Somecolumn
FROM tableA INNER JOIN tableB on TableA.Id = TableB.F_Id
WHERE ...
Dann füllt einen DataSet ds mit ihm. Dann
ds.Relations.Add("foo", ds.Tables[0].Columns("Id"), ds.Tables[1].Columns("ParentId"));
Schließlich können Sie einen Repeater auf der Seite hinzufügen, die Kommas für jede Zeile
legt <asp:DataList ID="Subcategories" DataKeyField="ParentCatId"
DataSource='<%# Container.DataItem.CreateChildView("foo") %>' RepeatColumns="1"
RepeatDirection="Horizontal" ItemStyle-HorizontalAlign="left" ItemStyle-VerticalAlign="top"
runat="server" >
Auf diese Weise werden Sie tun es Client-Seite, aber mit nur einer Abfrage, vorbei minimale Daten zwischen Datenbank und Frontend
habe ich versucht, die Lösung priyanka.sarkar erwähnt und die nicht ganz bekommen sie als OP fragte arbeiten. Hier ist die Lösung, die ich am Ende mit:
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
Lösung unter:
SELECT GROUP_CONCAT(field_attr_best_weekday_value)as RAVI
FROM content_field_attr_best_weekday LEFT JOIN content_type_attraction
on content_field_attr_best_weekday.nid = content_type_attraction.nid
GROUP BY content_field_attr_best_weekday.nid
verwenden, können Sie auch ändern die Joins
SELECT t.ID,
t.NAME,
(SELECT t1.SOMECOLUMN
FROM TABLEB t1
WHERE t1.F_ID = T.TABLEA.ID)
FROM TABLEA t;
Dies funktioniert aus verschiedener Tabelle mit Sub-Abfrage für die Auswahl.
Ich habe alle Antworten überprüft. Ich denke, in der Datenbank Einfügung sollte wie:
ID Name SomeColumn
1. ABC ,X,Y Z (these are three different rows)
2. MNO ,R,S
Das Komma am vorherigen Ende sein soll und Sie sucht nach wie %,X,%