Kombinieren Sie mehrere Ergebnisse in einer Unterabfrage in einem einzigen komma-separierte

StackOverflow https://stackoverflow.com/questions/111341

  •  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?

War es hilfreich?

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,%

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top