左外连接似乎无法正常工作

时间:2014-06-11 09:13:04

标签: sql sql-server-2005

我得到了这段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

在日历上,我有这样的事情:

CALENDAR

在CLIENT_MEDIDAS_COGEN上我有这个:

CLIENT_MEDIDAS_COGEN

最后,这是我得到的结果:

Result

问题是,我怎么可能没有获得第1小时和第2小时的行?我正在使用LEFT OUTER JOIN,但它似乎无法正常工作。

非常感谢您的帮助

3 个答案:

答案 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