Mam dwa stoliki:
TableA
------
ID,
Name
TableB
------
ID,
SomeColumn,
TableA_ID (FK for TableA)
Relacja to jeden wiersz TableA
- wiele z nich TableB
.
Teraz chcę zobaczyć taki wynik:
ID Name SomeColumn
1. ABC X, Y, Z (these are three different rows)
2. MNO R, S
To nie zadziała (wiele wyników w podzapytaniu):
SELECT ID,
Name,
(SELECT SomeColumn FROM TableB WHERE F_ID=TableA.ID)
FROM TableA
Jest to trywialny problem, jeśli wykonuję przetwarzanie po stronie klienta. Ale to oznacza, że będę musiał uruchamiać zapytania X na każdej stronie, gdzie X to liczba wyników TableA
.
Zauważ, że nie mogę po prostu wykonać GROUP BY lub czegoś podobnego, ponieważ zwróci wiele wyników dla wierszy TableA
.
Nie jestem pewien, czy UDF, wykorzystujący COALESCE lub coś podobnego może zadziałać?
sql-server
tsql
join
Donnie Thomas
źródło
źródło
1. Utwórz 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. Użyj w podzapytaniu:
SELECT ID, Name, dbo.CombineValues(FK_ID) FROM TableA
3. Jeśli korzystasz z procedury składowanej, możesz to zrobić:
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
źródło
Myślę, że z COALESCE jesteś na dobrej drodze. Zobacz tutaj, aby zobaczyć przykład tworzenia ciągu rozdzielanego przecinkami:
http://www.sqlteam.com/article/using-coalesce-to-build-comma-delimited-string
źródło
W MySQL jest funkcja group_concat , która zwraca to, o co prosisz.
SELECT TableA.ID, TableA.Name, group_concat(TableB.SomeColumn) as SomColumnGroup FROM TableA LEFT JOIN TableB ON TableB.TableA_ID = TableA.ID
źródło
Być może będziesz musiał podać więcej szczegółów, aby uzyskać bardziej precyzyjną odpowiedź.
Ponieważ zestaw danych wydaje się być wąski, możesz rozważyć użycie wiersza dla każdego wyniku i wykonanie przetwarzania końcowego na kliencie.
Więc jeśli naprawdę chcesz, aby serwer wykonał pracę, zwróci zestaw wyników, taki jak
co oczywiście jest prostym WEWNĘTRZNYM DOŁĄCZENIEM na ID
Gdy już masz zestaw wyników z powrotem na kliencie, utrzymuj zmienną o nazwie CurrentName i użyj jej jako wyzwalacza, kiedy przestaniesz zbierać SomeColumn do użytecznej rzeczy, którą chcesz, aby zrobiła.
źródło
Zakładając, że masz tylko klauzule WHERE w tabeli A, utwórz procedurę składowaną w ten sposób:
SELECT Id, Name From tableA WHERE ... SELECT tableA.Id AS ParentId, Somecolumn FROM tableA INNER JOIN tableB on TableA.Id = TableB.F_Id WHERE ...
Następnie wypełnij nim DataSet ds. Następnie
Na koniec możesz dodać repeater na stronie, który umieszcza przecinki dla każdej linii
<asp:DataList ID="Subcategories" DataKeyField="ParentCatId" DataSource='<%# Container.DataItem.CreateChildView("foo") %>' RepeatColumns="1" RepeatDirection="Horizontal" ItemStyle-HorizontalAlign="left" ItemStyle-VerticalAlign="top" runat="server" >
W ten sposób zrobisz to po stronie klienta, ale za pomocą tylko jednego zapytania, przekazując minimum danych między bazą danych a frontendem
źródło
Wypróbowałem rozwiązanie, o którym wspomniał priyanka.sarkar, ale nie działało ono tak, jak prosił OP. Oto rozwiązanie, które otrzymałem:
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
źródło
Rozwiązanie poniżej:
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
Użyj tego, możesz również zmienić połączenia
źródło
SELECT t.ID, t.NAME, (SELECT t1.SOMECOLUMN FROM TABLEB t1 WHERE t1.F_ID = T.TABLEA.ID) FROM TABLEA t;
To zadziała przy wybieraniu z innej tabeli za pomocą zapytania podrzędnego.
źródło
Przejrzałem wszystkie odpowiedzi. Myślę, że wstawianie do bazy danych powinno wyglądać następująco:
Przecinek powinien znajdować się na poprzednim końcu i wyszukiwać podobnie
%,X,%
źródło