2017-06-29 4 views
0

Kürzlich abgeholt SQL und ich habe ein Problem mit einer bestimmten korrelierten Unterabfrage.Wie man eine Variable in einer korrelierten Unterabfrage korrigiert (postgresql)

SELECT a.* 
FROM videos a 
WHERE EXISTS 
(SELECT NULL 
FROM actors b 
WHERE a.actor not ilike b.actor 
and a.title ilike ('%' + b.actor + '%')); 

Im Grunde möchte ich alle Einträge in der Video-Tabelle finden, die einen Schauspielers Namen im Titel hat, aber nicht markiert, wie in dem Video zu sein. Der obige Code gibt nur jedes Video in der Tabelle zurück, was vermutlich darauf zurückzuführen ist, dass die Unterabfrage nicht denselben "b.actor" in beiden Zeilen verwendet. Wie kann ich es ändern, um tatsächlich zu tun, was ich will? Danke im Voraus.

+2

Der String-Verkettungsoperator in SQL ist '||' nicht '+' –

Antwort

0

Zuerst || anstelle von + zu verketten Strings verwenden. Dann würde ich LEFT JOIN verwenden, um korrekte Beziehungen zwischen Videos und Schauspieler zu finden, mit GROUP BY auf Video-ID und das Sammeln Schauspieler IDs (falls vorhanden) mit array_agg(..):

select 
    v.id as video_id, 
    array_agg(a.id) actors_ids 
from videos v 
left join actors a on 
    v.title ilike ('%' || a.actor || '%') 
    and v.actor not ilike a.actor 
group by 1 
; 

Sie können aus Ergebnismenge Zeilen mit leeren Schauspieler entfernen mit HAVING. Oder einfach nur 'INNER JOIN verwenden nur die Videos zu bekommen, die zumindest die richtige Verbindung Akteure:

select 
    v.id as video_id, 
    array_agg(a.id) actors_ids 
from videos v 
join actors a on 
    v.title ilike ('%' || a.actor || '%') 
    and v.actor not ilike a.actor 
group by 1 
; 

schließlich diese ganze Ansatz ILIKE der Verwendung wird sehr langsam sein, wenn Ihre Tabellen groß sind. Und nicht streng - in vielen Fällen haben Sie falsche Treffer (wie "John" passt "Johnathan").

Betrachten Normalisierung (https://en.wikipedia.org/wiki/Database_normalization#Normal_forms) und arbeiten entweder mit EAV-Modell (https://en.wikipedia.org/wiki/Entity%E2%80%93attribute%E2%80%93value_model) oder mit Integer-Arrays oder JSONB-Datentyp.

Verwandte Themen