I got this piece of sql server 2005 code:
SELECT DT, a.id_uf, hora
FROM CALENDAR c LEFT OUTER JOIN CLIENT_MEDIDAS_COGEN a ON a.fecha_oferta = dt AND a.hora = c.H
WHERE
(id_tipo_medida IN (6, 1)) AND (id_magnitud = 1)
AND (DT BETWEEN '10/01/2013' AND '10/01/2013') AND (id_tipo_fact = 3)
ORDER BY DT, a.id_uf, a.hora
On calendar, I have got something like this:
On CLIENT_MEDIDAS_COGEN I have got this:
And finally, this is the result I am getting:
The question is, how is it possible I'm not getting the rows for hours 1 and 2?? I'm using LEFT OUTER JOIN but it just doesn't seem to work properly.
Thank you so much in advance for your help
Your WHERE
clause states that (id_magnitud = 1)
. Any rows in Calender
that were not joined to CLIENT_MEDIDAS_COGEN
will have NULL
in the id_magnitude
column.
SELECT
c.DT,
a.id_uf,
c.hora
FROM
CALENDAR c
LEFT OUTER JOIN CLIENT_MEDIDAS_COGEN a ON a.fecha_oferta = dt AND a.hora = c.H
WHERE
(c.DT BETWEEN '10/01/2013' AND '10/01/2013')
AND (COALESCE(a.id_tipo_medida, 1) IN (6, 1))
AND (COALESCE(a.id_magnitud, 1) = 1)
AND (COALESCE(a.id_tipo_fact, 3) = 3)
ORDER BY
c.DT, a.id_uf, a.hora
Also don't just use the table alias for common columns. Use them for all columns so it's clear where the column resides.
As per MatBaille's comment moving the filters on CLIENT_MEDIDAS_COGEN
to the join clause will perform better. The coalesce statments above just give an indication as to the reason for your issue. The below will likely perform better.
SELECT
c.DT,
a.id_uf,
c.hora
FROM
CALENDAR c
LEFT OUTER JOIN CLIENT_MEDIDAS_COGEN a ON
a.fecha_oferta = dt
AND a.hora = c.H
AND (a.id_tipo_medida IN (6, 1))
AND (a.id_magnitud = 1)
AND (a.id_tipo_fact = 3)
WHERE
(c.DT BETWEEN '10/01/2013' AND '10/01/2013')
ORDER BY
c.DT, a.id_uf, a.hora
That's because of where filters which make it work like inner join. You can move where filters to join conditions, like this:
SELECT c.ID, a.id_uf, c.H
FROM CALENDAR c LEFT OUTER JOIN CLIENT_MEDIDAS_COGEN a ON a.fecha_oferta = dt AND a.hora = c.H
AND
(a.id_tipo_medida IN (6, 1)) AND (a.id_magnitud = 1) AND (a.id_tipo_fact = 3)
WHERE (DT BETWEEN '10/01/2013' AND '10/01/2013')
ORDER BY DT, a.id_uf, a.hora
That will make the desired left join effect.
Cleaner (in my opinion) to use a subquery to apply the criteria to the right hand table in the join prior to the LEFT OUTER JOIN.
So it becomes...
SELECT c.ID, a.id_uf, c.H
FROM CALENDAR c
LEFT OUTER JOIN
(
SELECt id_uf, hora, fecha_oferta
FROM CLIENT_MEDIDAS_COGEN a
WHERE (id_tipo_medida IN (6, 1)) AND (id_magnitud = 1) AND (id_tipo_fact = 3)
) a ON a.fecha_oferta = dt AND a.hora = c.H
WHERE (DT BETWEEN '10/01/2013' AND '10/01/2013')
ORDER BY DT, a.id_uf, a.hora
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.