SQL 连接 3 个表(基于 2 个条件?)

标签 sql ms-access join

我有 3 个表设置如下(有点简化):

时间跟踪:id、tr_proj_id、tr_min、tr_type
time_projects:id,项目名称
time_tasks:id,任务名称

基本上,我想根据tr_type检索project_nametask_name,其值可以是“project”或“task”

一个例子

时间跟踪

+----+------------+--------+---------+
| id | tr_proj_id | tr_min | tr_type |
+----+------------+--------+---------+
|  1 |          3 |     60 | project |
|  2 |          3 |    360 | task    |
|  3 |          1 |    120 | project |
|  4 |          2 |     30 | project |
|  5 |          2 |     30 | task    |
|  6 |          1 |     90 | task    |
+----+------------+--------+---------+

时间项目

+----+------------------------+
| id |      project_name      |
+----+------------------------+
|  1 | Make someone happy     |
|  2 | Start a project        |
|  3 | Jump out of the window |
+----+------------------------+

时间任务

+----+---------------------+
| id |      task_name      |
+----+---------------------+
|  1 | drink a beer        |
|  2 | drink a second beer |
|  3 | drink more          |
+----+---------------------+

所需输出

+----+------------------------+------------+--------+---------+
| id |          name          | tr_proj_id | tr_min | tr_type |
+----+------------------------+------------+--------+---------+
|  1 | Jump out of the window |          3 |     60 | project |
|  2 | drink more             |          3 |    360 | task    |
|  3 | Make someone happy     |          1 |    120 | project |
|  4 | Start a project        |          2 |     30 | project |
|  5 | drink a second beer    |          2 |     30 | task    |
|  6 | drink a beer           |          1 |     90 | task    |
+----+------------------------+------------+--------+---------+

而且在整个 JOIN 事情上真的很糟糕,这是我迄今为止想到的唯一的东西(这不起作用..):

SELECT tt.tr_proj_id, tt.tr_type, tt.tr_min, pp.project_name, pp.id, ta.task_name, ta.id
FROM time_tracking as tt, time_projects as pp, time_tasks as ta 
WHERE ((tt.tr_type = 'project' AND pp.id = tt.tr_proj_id) OR (tt.tr_type = 'task' AND ta.id = tt.tr_proj_id)) 
AND tt.tr_min > 0
ORDER BY tt.tr_proj_id DESC

如果有人知道如何执行此操作,请随时分享!


更新:看来我忘记指定我正在使用access 数据库。这显然不接受诸如 CASEcoalesce 之类的东西。显然有 IIF() 但我不太确定如何在这种情况下使用它。

最佳答案

使用 join 子句并将连接条件从 where 子句移至 on 子句:

SELECT
    tt.tr_proj_id,
    tt.tr_type,
    tt.tr_min,
    pp.project_name,
    pp.id,
    ta.task_name,
    ta.id
FROM time_tracking as tt
left join time_projects as pp on tt.tr_type = 'project' AND pp.id = tt.tr_proj_id
left join time_tasks as ta on tt.tr_type = 'task' AND ta.id = tt.tr_proj_id
WHERE tt.tr_min > 0
ORDER BY tt.tr_proj_id DESC,tt.tr_day ASC

我使用了左连接,它会从主表中为您提供一行,即使该连接不存在(如果没有连接,您将从连接表中的列中获取空值) )


这里的一个关键点是,许多 SQL 程序员没有意识到,ON 子句可能包含任何条件,甚至不是来自连接表的条件(如本例所示)。许多程序员认为条件必须只是与正式外键关系相关的条件。

关于SQL 连接 3 个表(基于 2 个条件?),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/13518647/

相关文章:

sql - 根据另一个表更新行

mysql - 更正公式的 SQL 脚本

ms-access - VBA:DateDiff 年假

mysql - 加载数据时,Access 接近 2GB 限制

c# - 添加数据源后,如何 Access ?

mysql - 在两个不同数据库中的表之间连接?

php - 如果不在另一个查询中,请选择 ROW

sql - 获取与列值的表连接

java - Hadoop Mapper 中未调用设置方法

python - 使用 python 将两个文件中的每一行连接为一行