SQL条件JOIN - 基于joined_table条件定义的JOIN点

时间:2015-10-26 20:21:31

标签: mysql sql postgresql postgresql-9.3

情境:
在下面的每一个中,"创建日期"," other_created_date"和"日期"是一天(即2012-01-03)

表1:
字段:
ID | CREATED_DATE

表2:
字段:
ID | table_1_fk | other_created_date

表3:
字段:
日期

目标:

我想做以下事情:

SELECT * FROM table_1
JOIN table_2
ON table_1.id = table_2.table_1_fk
FULL OUTER JOIN table_3
ON table_3.date = ( 
    CASE 
        WHEN table_1.created_date > table_2.other_created_date THEN table_1.created_date
        ELSE table_2.other_created_date
        END
)

基本上,我感兴趣的是(Table_1 + Table_2)在Table_3上加入,如果第一个语句为true,我们加入Table_1的日期,如果第二个语句为true,我们加入Table_2&# 39; s日期

这可能还是有更好的方法可以解决这个问题?

2 个答案:

答案 0 :(得分:2)

SELECT * FROM table_1
JOIN table_2
ON table_1.id = table_2.table_1_fk
FULL OUTER JOIN table_3
ON table_3.date = GREATEST(table_1.created_date,table_2.other_created_date)

答案 1 :(得分:1)

我喜欢Bernd的回答。但是,在不知道这些表的内容的情况下,我认为评估执行建议和仅具有两个单独的外连接之间的性能差异是值得的。我知道我之前在联接中做过创造性的事情,数据库会管理它,但它如何管理它可能根本不是我想到的,特别是如果处理数以千万计的记录。

作为一个例子,如果您使用两个外部联接而不是尝试将它们合并为一个,那么这就是SQL的样子。它可能会有更多代码,这就是为什么你需要对它进行基准测试以确定它是否重要。

我知道我在这里使用了左连接 - 当我看到一个完整的外部时,我总是有点怀疑,但并不是说它不是你想要的。但这仅用于说明目的:

SELECT
  case
    when table_1.created_date > table_2.other_created_date then
      t3a.<field_1>
    else
      t3b.<field_1>
  end
FROM
  table_1
  JOIN table_2
    ON table_1.id = table_2.table_1_fk
  left join table3 t3a on
    table3.date = table_1.created_date
  left join table3 t3b on
    table3.date = table_2.other_created_date

- 编辑 -

以下是一个示例,其中紧凑编码的连接条件具有可怕的性能,并且解决方法更多的代码但是值得:

PostgreSQL Joining Between Two Values