我得到了这段sql server 2005代码:
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
在日历上,我有这样的事情:
在CLIENT_MEDIDAS_COGEN上我有这个:
最后,这是我得到的结果:
问题是,我怎么可能没有获得第1小时和第2小时的行?我正在使用LEFT OUTER JOIN,但它似乎无法正常工作。
非常感谢您的帮助
答案 0 :(得分:1)
您的WHERE
条款声明(id_magnitud = 1)
。 Calender
中未加入CLIENT_MEDIDAS_COGEN
的所有行都会在NULL
列中显示id_magnitude
。
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
另外,不要只使用常用列的表别名。将它们用于所有列,以便明确列所在的位置。
根据MatBaille的评论,将CLIENT_MEDIDAS_COGEN
上的过滤器移动到join子句会更好。上面的合并声明只是表明您的问题的原因。以下可能表现更好。
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
答案 1 :(得分:1)
那是因为过滤器使其像内部连接一样工作。您可以移动过滤器加入条件的位置,例如:
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
这将产生所需的左连接效果。
答案 2 :(得分:0)
Cleaner(在我看来)使用子查询将条件应用于LEFT OUTER JOIN之前的连接中的右手表。
所以它变成......
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