PostgreSQL
 sql >> Baza danych >  >> RDS >> PostgreSQL

Postgres – Wiele sprzężeń powoduje, że moje zapytanie zwraca nieprawidłowe dane

Buduj złożony SQL krok po kroku.

W ten sposób otrzymasz książki, które mają oba wymagane znaczniki. Jest tak niezawodny, jak definicja tabeli. Twoja definicja tabeli nie powinna pozwalać, aby jedna książka miała dwa razy ten sam tag. Potrzebujesz UNIKALNEGO ograniczenia (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

Możesz użyć tego w 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

Dołączenie do tabeli głosów powinno usunąć book_id 6 z wyniku. (Brak głosów na 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

Teraz możesz dodać kolumnę głosowania do zapytania.

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

Na koniec możesz zsumować głosy.

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

Twoja wersja nie działa, ponieważ zwraca nieprawidłowe numery identyfikacyjne książki. Połączenie JOIN na books_votes i klauzuli WHERE nie działa zgodnie z oczekiwaniami.

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

Książka 2 jest dołączona nie dlatego, że ma oba znaczniki, ale dlatego, że ma dwa głosy.

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. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. Postgres - Przekazywanie nazwy tabeli jako parametru i przechowywanie wyniku w pliku

  2. Postgres prosty stół „przestawny”

  3. Zapisz bazę danych na zewnętrznym dysku twardym

  4. PostgreSQL - wyświetlanie pierwszego wiersza jako sumy pozostałych wierszy

  5. Apache Cayenne / PostgreSQL:zbyt wiele klientów już wystąpiło błąd