sql >> Databasteknik >  >> RDS >> PostgreSQL

Postgres - Multiple joins gör att min fråga returnerar felaktig data

Bygg komplex SQL steg för steg.

Detta ger dig de böcker som har båda de nödvändiga taggarna. Det är bara så tillförlitligt som din tabelldefinition. Din tabelldefinition bör inte tillåta en bok att ha samma tagg två gånger. Du behöver en UNIK begränsning på (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

Du kan använda det i en 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

Att gå med på röstbordet bör ta bort book_id 6 från resultatet. (Inga röster för 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 kan du lägga till röstkolumnen i frågan.

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

Slutligen kan du summera rösterna.

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

Din version fungerar inte eftersom den returnerar fel bok-id-nummer. Kombinationen av JOIN på books_votes och WHERE-satsen gör inte vad du förväntade dig att den skulle göra.

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

Bok 2 ingår inte för att den har båda taggarna, utan för att den har två röster.

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. MySQL hur man sammanfogar tabeller på två fält

  2. Automatisera mysql_secure_installation med echo-kommando via ett skalskript

  3. MySQL Hur returnerar man unika/distinkta resultat?

  4. Beräkna skillnaden mellan datum i Postgresql