Verketten mehrere Felder in einer mit SQL
Frage
Ich habe drei Tabellen tag
, page
, pagetag
Mit den Daten unter
Seite
ID NAME
1 page 1
2 page 2
3 page 3
4 page 4
Tags
ID NAME
1 tag 1
2 tag 2
3 tag 3
4 tag 4
pagetag
ID PAGEID TAGID
1 2 1
2 2 3
3 3 4
4 1 1
5 1 2
6 1 3
Ich möchte gerne einen string mit dem Korrespondent der-tag-Namen für jede Seite, die mit SQL in einer einzigen Abfrage.Dies ist meine gewünschte Ausgabe.
ID NAME TAGS
1 page 1 tag 1, tag 2, tag 3
2 page 2 tag 1, tag 3
3 page 3 tag 4
4 page 4
Ist dies möglich mit SQL?
Ich bin mit MySQL.Nichtsdestoweniger ich möchte eine Datenbank-Hersteller unabhängige Lösung, wenn möglich.
Lösung
Sergio del Amo:
Jedoch, ich bin nicht immer der Seiten ohne tags.Ich glaube, ich muss schreiben, meine Abfrage mit left outer joins.
SELECT pagetag.id, page.name, group_concat(tag.name)
FROM
(
page LEFT JOIN pagetag ON page.id = pagetag.pageid
)
LEFT JOIN tag ON pagetag.tagid = tag.id
GROUP BY page.id;
Nicht eine sehr hübsche Abfrage, aber sollte Ihnen das geben, was Sie wollen - pagetag.id
und group_concat(tag.name)
werden null
Seite 4 in dem Beispiel, das Sie oben gepostet habe, aber die Seite wird in den Ergebnissen angezeigt.
Andere Tipps
Ja, Sie können tun es über die 3 etwas wie die unten:
SELECT page_tag.id, page.name, group_concat(tags.name)
FROM tag, page, page_tag
WHERE page_tag.page_id = page.page_id AND page_tag.tag_id = tag.id;
Hat nicht getestet worden und könnte wohl geschrieben werden, ein bisschen effizienter, aber das sollte Ihnen den Einstieg!
Auch MySQL ist angenommen, so kann nicht spielen so schön mit MSSQL!Und MySQL ist nicht wild über Bindestriche in das Feld Namen, so verändert Unterstriche in den obigen Beispielen.
So weit ich bin mir bewusst, SQL92 nicht definieren, wie die string-Verkettung getan werden sollte.Dies bedeutet, dass die meisten Motoren haben Ihre eigene Methode.
Wenn Sie möchten, dass eine Datenbank-unabhängige Methode, Sie ' ll haben zu tun es außerhalb der Datenbank.
(ungetestet in allen, aber Oracle)
Oracle
SELECT field1 | ', ' | field2
FROM table;
MS SQL
SELECT field1 + ', ' + field2
FROM table;
MySQL
SELECT concat(field1,', ',field2)
FROM table;
PostgeSQL
SELECT field1 || ', ' || field2
FROM table;
Ich habe eine Lösung spielen mit joins.Die Abfrage ist:
SELECT
page.id AS id,
page.name AS name,
tagstable.tags AS tags
FROM page
LEFT OUTER JOIN
(
SELECT pagetag.pageid, GROUP_CONCAT(distinct tag.name) AS tags
FROM tag INNER JOIN pagetag ON tagid = tag.id
GROUP BY pagetag.pageid
)
AS tagstable ON tagstable.pageid = page.id
GROUP BY page.id
Und zu dieser Ausgabe:
id name tags
---------------------------
1 page 1 tag2,tag3,tag1
2 page 2 tag1,tag3
3 page 3 tag4
4 page 4 NULL
Ist es möglich, steigern Sie die Geschwindigkeit von Abfragen schreiben es einen anderen Weg?
pagetag.id und group_concat(Tags.name) wird null für die Seite 4 im Beispiel oben gepostet habe, aber die Seite wird in den Ergebnissen angezeigt.
Sie verwenden können die COALESCE
Funktion zum entfernen der Nullen, wenn Sie benötigen:
select COALESCE(pagetag.id, '') AS id ...
Es wird wieder das erste nicht-null-Wert aus der Liste der Parameter.
Ich glaube, Sie kann verwenden müssen, um mehrere updates.
So etwas wie (nicht getestet):
select ID as 'PageId', Name as 'PageName', null as 'Tags'
into #temp
from [PageTable]
declare @lastOp int
set @lastOp = 1
while @lastOp > 0
begin
update p
set p.tags = isnull(tags + ', ', '' ) + t.[Tagid]
from #temp p
inner join [TagTable] t
on p.[PageId] = t.[PageId]
where p.tags not like '%' + t.[Tagid] + '%'
set @lastOp == @@rowcount
end
select * from #temp
Hässlich, aber.
Das Beispiel T-SQL, aber ich denke, MySql hat-äquivalente für alles verwendet.