sql >> Databáze >  >> RDS >> PostgreSQL

Postgres - Vícenásobné spojení způsobuje, že můj dotaz vrací nesprávná data

Vytvářejte složité SQL krok za krokem.

Získáte tak knihy, které mají oba požadované štítky. Je to jen tak spolehlivé jako definice vaší tabulky. Vaše definice tabulky by neměla umožňovat, aby jedna kniha měla stejnou značku dvakrát. Potřebujete UNIKÁTNÍ omezení (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

Můžete to použít v 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

Zařazení do tabulky hlasů by mělo z výsledku vypadnout book_id 6. (Žádné hlasy pro 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

Nyní můžete k dotazu přidat sloupec hlasování.

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

Nakonec můžete sečíst hlasy.

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

Vaše verze nefunguje, protože vrací nesprávná identifikační čísla knihy. Kombinace JOIN na books_votes a klauzule WHERE nedělá to, co jste od ní očekávali.

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

Kniha 2 není zahrnuta proto, že má oba štítky, ale protože má dva hlasy.

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. Hledáme řazení MySQL bez rozlišení velkých a malých písmen, kde a !=ä

  2. Odstranění duplicitních řádků z tabulky

  3. Parametr 'param_name' nebyl v kolekci nalezen

  4. při vkládání více řádků do sql dochází k chybě