sql >> Databáze >  >> RDS >> Mysql

Připojte více tabulek a zachovejte hodnoty NULL

Když použijete vnější spojení a poté použijete jeden z "vnějších" sloupců při kontrole rovnosti v WHERE klauzule převedete vnější spojení na vnitřní spojení. Je to proto, že vaše podmínka, která kontroluje soukromí příspěvku, vyžaduje, aby tam příspěvek byl:

AND p.privacy = 1 OR (p.privacy = 2 AND fr.fstatus = 1)

Když má vnější spojení vytvořit řádek, který odpovídá oznámení bez příspěvku, zkontroluje výše uvedenou podmínku. Protože tam příspěvek není, p.privacy bude vyhodnoceno jako NULL , "kontaminující" obě strany OR a nakonec se celá podmínka vyhodnotí jako false .

Přesunutí této podmínky do ON podmínka spojení problém vyřeší:

SELECT
  u.username AS sender,
  ux.username AS receiver,
  p.id
FROM notifications n
JOIN follows f ON (n.user_id = f.tofollow_id)
JOIN follows fr ON (n.tonotify_id = fr.tofollow_id)
JOIN user u ON (u.id = n.user_id)
JOIN user ux ON (ux.id = n.tonotify_id)
LEFT JOIN posts p ON (n.posts_id = p.id)
                 AND (p.privacy = 1 OR (p.privacy = 2 AND fr.fstatus = 1))
WHERE f.user_id = 1
  AND fr.user_id = 1
  AND f.status = 1
ORDER BY n.id DESC

Dalším způsobem, jak to opravit, by bylo přidání IS NULL podmínku na váš OR , takto:

SELECT
  u.username AS sender,
  ux.username AS receiver,
  p.id
FROM notifications n
JOIN follows f ON (n.user_id = f.tofollow_id)
JOIN follows fr ON (n.tonotify_id = fr.tofollow_id)
JOIN user u ON (u.id = n.user_id)
JOIN user ux ON (ux.id = n.tonotify_id)
LEFT JOIN posts p ON (n.posts_id = p.id)
WHERE f.user_id = 1
  AND fr.user_id = 1
  AND f.status = 1
  AND (p.privacy IS NULL OR p.privacy = 1 OR (p.privacy = 2 AND fr.fstatus = 1))
ORDER BY n.id DESC


  1. Jak přepočítat pole na GROUP

  2. jak získat čas načítání v milisekundách nebo mikrosekundách v mysql

  3. Připojení C# Mysql v konfiguraci souboru txt

  4. Aktualizace schématu Symfony2 Doctrine se nezdařila