2

我有几个带有日期的表,我试图加入这些表以创建一个大表,其中数据按日期分组。

我现在通过 LEFT JOIN'ing 到从我需要加入的表生成的子选择来完成此操作(其中很多是同一个表,具有不同的 where 查询并涉及 SUM 和 COUNT 所以我认为我必须使用子选择)。我遇到的问题是,如果第一个表中不存在某个日期,那么即使后续表中存在与该日期连接的行,它也不会显示在表中。我根据 DATE(datetime_column) 加入。

所以就像

SELECT date, col 1 
FROM a 
   LEFT JOIN (SELECT date, col2 FROM a1) a2 ON DATE(a.date)=DATE(a2.date) 
   LEFT JOIN (SELECT date, col3 FROM a3) a4 ON DATE(a3.date)=DATE(a4.date) 

说得通?可能不是..

4

3 回答 3

1

基本上有两种方法可以做到这一点:

您可以使用FULL OUTER JOIN

全外连接

从概念上讲,完全外连接结合了应用左外连接和右外连接的效果。如果 FULL OUTER JOINed 表中的记录不匹配,则结果集对于缺少匹配行的表的每一列都将具有 NULL 值。对于那些匹配的记录,将在结果集中生成一行(包含从两个表中填充的字段)。

...

一些数据库系统不直接支持完全外连接功能,但它们可以通过使用内连接和 UNION ALL 分别从左表和右表中选择“单表行”来模拟它。相同的示例可以如下所示:

SELECT employee.LastName, employee.DepartmentID, department.DepartmentName, department.DepartmentID
FROM employee
INNER JOIN department ON employee.DepartmentID = department.DepartmentID

UNION ALL

SELECT employee.LastName, employee.DepartmentID, CAST(NULL AS VARCHAR(20)), CAST(NULL AS INTEGER)
FROM employee
WHERE NOT EXISTS (SELECT * FROM department WHERE employee.DepartmentID = department.DepartmentID)

UNION ALL

SELECT CAST(NULL AS VARCHAR(20)), CAST(NULL AS INTEGER),
department.DepartmentName, department.DepartmentID
FROM department
WHERE NOT EXISTS (SELECT * FROM employee WHERE employee.DepartmentID = department.DepartmentID)

其他方式您可以制作一个主视图,女巫包含所有表的所有不同键,以便与所有表进行 LEFT JOIN。

select *
from (
        SELECT date
        FROM a
        union
        SELECT date
        FROM a1
        union
        SELECT date
        FROM a3
    ) 
    LEFT JOIN a using (date)
    LEFT JOIN a1 using (date)
    LEFT JOIN a3 using (date)

有时我更喜欢 FULL OUTER JOIN 的第二种方式,因为许多 RDBMS 不支持 FULL OUTER JOIN 并且因为有许多支持它的人没有很好地优化它,例如 Oracle 的当前版本只是威胁一个完整的外部连接作为引用中显示的等效查询,女巫对表演非常有损。

于 2012-07-22T13:08:58.220 回答
0

尝试使用 OUTER JOIN 从主表中获取所有记录,并仅从子/子表中获取匹配记录。

SELECT a.Col1, b.Col1 FROM a LEFT OUTER JOIN b ON a.Col2=b.Col2

有关联接的详细信息,请参阅联接 (SQL)

于 2012-07-22T07:53:44.057 回答
0

为此,您还有另一种选择,根本不使用连接。您可以使用联合和聚合将结果放在一起:

SELECT date, max(col1) as col1, max(col2) as col2, max(col3) as col3
FROM ((select date, col1, NULL as col2, NULL as col3 from a1) union all
      (SELECT date, NULL, col2, NULL FROM a2) union all 
      (SELECT date, NULL, NULL, col3 FROM a3)
     ) t
group by date 

通常解决方案是 Alessandro 给出的第二个(第一个版本非常麻烦)。一个警告。他的解决方案从数据中提取日期。有时您想生成主列表,可能来自日历表,或者可能通过生成日期列表(具体情况完全取决于数据库)。

于 2012-07-22T13:41:53.497 回答