【问题标题】:SQL conditional JOIN - JOIN point defined based on joined_table conditionsSQL 条件 JOIN - 根据joined_table 条件定义的连接点
【发布时间】:2015-10-27 04:48:13
【问题描述】:

场景:
在下面的每一个中,“created date”、“other_created_date”和“date”都是一天(即 2012-01-03)

表 1:
领域:
身份证 |创建日期

表 2:
领域:
身份证 | 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) JOINed on Table_3 感兴趣,如果第一个语句为真,我们在 Table_1 的日期加入,如果第二个语句为真,我们在 Table_2 的日期加入

这是可能的还是有更好的方法?

【问题讨论】:

  • 我宁愿以固定方式加入table3两次,并使用条件表达式在选择列表中选择正确的值。
  • @Shadow 你能提供一个查询示例吗?现在我把它分解成两个单独的查询,然后我只是用不同的语言添加这两组,但我正试图把这一切都放到 SQL 中
  • 你能清理一下这个问题的标签吗

标签: mysql sql postgresql postgresql-9.3


【解决方案1】:
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)

【讨论】:

  • 我希望我能轻松地传达一个更好的感觉,即这为我节省了多少时间和精力......我已经在这个问题上待了几天的大部分时间。谢谢,这工作得很好
【解决方案2】:

我喜欢 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

【讨论】:

  • 感谢@Hambone,我将再次使用此语法,将其与 Bernd 未来的解决方案进行基准测试 - 我很欣赏提出解决问题的第二种方法的想法。
  • 关于 FULL OUTER - 我选择它的原因是我的 table_3 实际上只是生成的一系列日期(天),并且 FULL OUTER 确保计数为 0 的行是仍然包括在内...尽管也可能有更好的方法来实现这一目标
  • 确实有道理——谢谢。您是否考虑过 generate_series() 而不是您的 table3?
  • 是的,这实际上就是 table3,是 generate_series(),但我在这里只是将其称为 table3,以使问题简单易懂
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2023-03-06
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多