Skip to content
Advertisement

SQL left join exclude non matching records

I’m working on this query (running on MySQL 5.6):

SELECT 
    veicoli_contratti.targa AS targa,
    veicoli_contratti.canone_noleggio AS canone,
    anag_convenzionati.nome AS convenzionato,
    SUM(noleggio_veicoli.fatt_prezzo_totale_noleggio) AS noleggi_incasso,
    noleggio_veicoli.modalita_noleggio,
    COUNT(DISTINCT noleggio_veicoli.id) AS noleggi    
FROM
    veicoli_contratti
        LEFT JOIN
    noleggio_veicoli ON veicoli_contratti.id = noleggio_veicoli.id_veicolo
        INNER JOIN
    anag_convenzionati ON veicoli_contratti.id_convenzionato = anag_convenzionati.id
WHERE
        (veicoli_contratti.data_cancellazione IS NULL)
        AND (veicoli_contratti.targa <> '')
        AND (noleggio_veicoli.data_cancellazione IS NULL)
        AND (anag_convenzionati.data_cancellazione IS NULL)
        AND (YEAR(noleggio_veicoli.rientro_data) = 2020)
        AND (MONTH(noleggio_veicoli.rientro_data) = 10)
        AND ((noleggio_veicoli.stato_noleggio = 'C')
              OR (noleggio_veicoli.stato_noleggio = 'F')
            )
        AND ((noleggio_veicoli.modalita_noleggio = 'S')
             OR (noleggio_veicoli.modalita_noleggio = 'OPO')
             OR (noleggio_veicoli.modalita_noleggio = 'M')
            )
        AND (veicoli_contratti.stato = 'OPERATIVA')
GROUP BY anag_convenzionati.id , veicoli_contratti.id , noleggio_veicoli.modalita_noleggio
ORDER BY convenzionato , noleggi DESC , canone DESC , noleggi_incasso DESC ;

I thought LEFT JOIN clause will produce a record even if there’s not a matching record in table noleggio_veicoli but this doesn’t happen. The result include just records where a match is found between veicoli_contratti and noleggio_veicoli. I tried also adding OR noleggio_veicoli.id IS NULL in WHERE clause but it’s not the solution. How can I fix this? I created an SQL fiddle to try this here

Advertisement

Answer

Your understand is correct. However, the where clause is “undoing” the LEFT JOIN. Why?

You have conditions such as this:

   AND ((noleggio_veicoli.stato_noleggio = 'C') OR (noleggio_veicoli.stato_noleggio = 'F'))

Well, NULL fails those conditions so non-matches are filtered out. This condition (along with other conditions) should be included in the ON clause. For this one, it looks like:

   AND noleggio_veicoli.stato_noleggio IN ('C', 'F')
User contributions licensed under: CC BY-SA
2 People found this is helpful
Advertisement