sql >> Database >  >> RDS >> PostgreSQL

Postgres - Meerdere joins zorgen ervoor dat mijn query onjuiste gegevens retourneert

Bouw stap voor stap complexe SQL.

Dit geeft u de boeken die beide de vereiste tags hebben. Het is slechts zo betrouwbaar als uw tabeldefinitie. Uw tabeldefinitie mag niet toestaan ​​dat een boek twee keer dezelfde tag heeft. Je hebt een UNIEKE beperking nodig voor (book_id, tag_id).

SELECT book_id 
FROM books_tags
WHERE books_tags.tag_id IN (716, 101)
GROUP BY book_id
HAVING COUNT(tag_id) = 2

book_id
--
6
3

Je kunt dat gebruiken in een JOIN.

SELECT books.id
FROM books
INNER JOIN (
    SELECT book_id 
    FROM books_tags
    WHERE books_tags.tag_id IN (716, 101)
    GROUP BY book_id
    HAVING COUNT(tag_id) = 2) bt ON bt.book_id = books.id

book_id
--
6
3

Deelnemen aan de stemtafel zou book_id 6 uit het resultaat moeten halen. (Geen stemmen voor 6.)

SELECT books.id
FROM books
INNER JOIN (
    SELECT book_id 
    FROM books_tags
    WHERE books_tags.tag_id IN (716, 101)
    GROUP BY book_id
    HAVING COUNT(tag_id) = 2) bt ON bt.book_id = books.id
INNER JOIN books_votes bv ON bv.book_id = books.id

book_id
--
3

Nu kunt u de stemkolom aan de zoekopdracht toevoegen.

SELECT books.id, bv.vote
FROM books
INNER JOIN (
    SELECT book_id 
        FROM books_tags
    WHERE books_tags.tag_id IN (716, 101)
    GROUP BY book_id
    HAVING COUNT(tag_id) = 2) bt ON bt.book_id = books.id
INNER JOIN books_votes bv ON bv.book_id = books.id

book_id  vote
--
3        1

Ten slotte kun je de stemmen optellen.

SELECT books.id, SUM(bv.vote) AS total_votes
FROM books
INNER JOIN (
    SELECT book_id 
        FROM books_tags
    WHERE books_tags.tag_id IN (716, 101)
    GROUP BY book_id
    HAVING COUNT(tag_id) = 2) bt ON bt.book_id = books.id
INNER JOIN books_votes bv ON bv.book_id = books.id
GROUP BY books.id;

book_id  total_votes
--
3        1

Uw versie werkt niet, omdat deze de verkeerde boek-ID-nummers retourneert. De combinatie van de JOIN op books_votes en de WHERE-clausule doet niet wat je ervan verwachtte.

SELECT books.id AS books_id
FROM books
JOIN books_votes ON books.id = books_votes.book_id
JOIN books_tags ON books.id = books_tags.book_id
WHERE books_tags.tag_id IN (716, 101)
GROUP BY books.id 

books_id
--
3
2

Boek 2 is niet opgenomen omdat het beide tags heeft, maar omdat het twee stemmen heeft.

SELECT books.id AS books_id, books_tags.tag_id, books_votes.vote
FROM books
JOIN books_votes ON books.id = books_votes.book_id
JOIN books_tags ON books.id = books_tags.book_id
WHERE books_tags.tag_id IN (716, 101)
ORDER BY books_id, tag_id

book_id  tag_id     vote
--
2        101        1
2        101        1
3        101        1
3        716        1


  1. Gebruik OBJECT_NAME() om de naam van een object op te halen uit zijn object_id in SQL Server

  2. Wat is in SQL / MySQL het verschil tussen ON en WHERE in een join-instructie?

  3. Extraheer specifieke velden uit tekstbestand

  4. Hoe ontsnap ik aan een gereserveerd woord in Oracle?