【问题标题】:Sql conditional Join on different tablesSql条件连接不同的表
【发布时间】:2014-12-30 04:37:33
【问题描述】:

我要在现有项目上添加通知模块。 我的表结构和图片一样。

图片:

正如您在图片中看到的,每个通知都有一个类型和一个相关 ID。

类型 1 = 预订被取消,相关 ID 是“预订”表上的 id

类型 3 = 帐户余额低于给定的最小值。限制所以 releatedID 是“account_movements”上的 id 表

我正在尝试做的是条件连接,以避免 2 个不同的 sql 查询;

  1. 获取属于此人的所有通知
  2. 根据“notification.Type”从不同的表中获取通知详情

所以问题是我可以在一个查询中完成吗?

【问题讨论】:

    标签: mysql join conditional-statements


    【解决方案1】:

    类似下面的东西应该可以工作。基本上,您指定notifications 表中的哪些记录与reservations 表或account_movements 表中的记录在您加入这些记录时连接。使用LEFT JOIN 以便您的所有notification 记录通过,并且只有reservations 表或account_movements 中匹配的记录才能通过。

    SELECT 
      n.id,
      n.type,
      n.companyid,
      n.personid,
      n.relatedid,
      n.description,
      r.details as reservation_details,
      am.details as account_movement_details,
      COALESCE(r.details, am.details) AS combined_detail
    FROM
      notifications n
      LEFT OUTER JOIN reservations r ON
        n.relatedid = r.id AND
        n.type = 1
      LEFT OUTER JOIN account_movements am ON
        n.relatedid = am.id AND
        n.type = 3
    

    这里有一个SQL FIDDLE 也有解决方案。

    我在COALESCE() 中添加只是为了表明,由于 JOINS 是互斥的,因此您可以安全地将 reservations 表和 account_movements 表中的列合并到一个列中,而不必担心丢失或重复任何数据.

    【讨论】:

      【解决方案2】:

      如果你做一个左连接,你将不必有任何条件:

      SELECT * FROM notifications n
      LEFT JOIN reservations r ON n.releatedID = r.id
      LEFT JOIN account_movements m ON m.releatedID = m.id
      

      【讨论】:

      • 如果reservation 和account_movements 表都有一个ID 等于releatedID 的条目会发生什么?我不会变得比两个表中的条目都好吗?
      • 如果在reservation 和account_movements 中有记录,您将得到一行包含所有通知数据、所有预订数据和所有account_movements 数据的行,每个数据都以它们的表名作为前缀。在您查询后将执行的代码中,您会将通知类型记入帐户并相应地保留预订或 account_movement 数据。
      • @JNevill 回答更完整,只允许检索所需的数据。
      • 这是一个有价值的解决方案,但您可能需要在 @ 中的每个 reservation 和/或 account_movement 记录上做一些广泛的 CASEIFCOALESCE 987654327@ 子句和一个GROUP BY 整体以防止notifications 记录重复。如果你在SELECT 子句中加上一个星号,它可能会有点麻烦。
      猜你喜欢
      • 2022-01-01
      • 2021-09-04
      • 1970-01-01
      • 2018-05-02
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多