在 LEFT JOIN 中使用 OR 条件

Using an OR condition in LEFT JOIN

这是我在 2 table 秒内得到的。

TABLE tbl_appuntamento => 此 table 包含约会列表

    +------+----------------------+-----------+---------+
    | id   | data                 | slot      | id_sede |
    +------+----------------------+-----------+---------+
    | 1    | 2017-03-27           | 10:00:00  | 1       |
    | 2    | 2017-03-27           | 10:00:00  | 1       |
    | 3    | 2017-03-28           | 11:00:00  | 1       |
    | 4    | 2017-03-28           | 12:00:00  | 1       |
    +------+----------------------+-----------+---------+

TABLE tbl_blocco_operativo => 此 table 包含无法设置约会的日期或时段列表

    +------+----------------------+-----------+---------+------------+
    | id   | data                 | slot      | id_sede | is_fullday |
    +------+----------------------+-----------+---------+------------+
    | 1    | 2017-03-27           | 10:00:00  | 1       |0           |
    | 2    | 2017-03-27           | 11:00:00  | 1       |0           |
    | 3    | 2017-03-28           | 00:00:00  | 1       |1           |
    +------+----------------------+-----------+---------+------------+

我有这个问题

    SELECT appuntamento.*,blocco.slot blockSlot, blocco.is_fullday blockFullday 
    FROM tbl_appuntamento appuntamento 
    LEFT JOIN tbl_argomento argomento ON argomento.id = appuntamento.id_argomento
    LEFT JOIN  tbl_blocco_operativo blocco ON blocco.data = appuntamento.data AND blocco.id_sede = appuntamento.id_sede 
        AND ((blocco.is_fullday = 0 AND blocco.slot = appuntamento.slot) 
             OR (blocco.is_fullday = 1 AND blocco.slot <> appuntamento.slot))
    WHERE appuntamento.id_sede = :locationId
    AND appuntamento.data >= :startDate
    AND appuntamento.data <= :endDate
    GROUP BY appuntamento.id
    ORDER BY appuntamento.data, appuntamento.slot

目标是插入结果中第二个 table 的 "is_fullday" 和 "slot" 列,以检查是否与计划有任何冲突,因为约会可能在任何人在 table "blocco_operativo"

中创建记录之前被预订

现在这似乎可行,但我不确定第二个 JOIN 中的 "OR" 条件是否是最佳解决方案。 可以吗,还是我漏了什么?

您可以将 OR 表达式替换为:

blocco.is_fullday = (blocco.slot <> appuntamento.slot)

这是有效的,因为括号之间的布尔表达式将对应于数字 0 或 1,这正是您想要 blocco.is_fullday 与之进行比较的。

更详细地说,这可以写成:

blocco.is_fullday = case blocco.slot when appuntamento.slot then 0 else 1 end

全天案例

如果一整天都被封锁,您可以认为 时段 无关紧要。在这种情况下,条件可以简化为:

(blocco.is_fullday = 1 OR blocco.slot = appuntamento.slot)

因为 is_fullday 就像一个布尔值,你可以说:

(blocco.is_fullday OR blocco.slot = appuntamento.slot)

非常接近。我认为在全天的情况下,您根本不需要检查 slot。按照您编写的方式,如果在 00:00 时段中安排了约会,则将认为全天时段可用。 (如果公司在午夜不营业,也许这实际上不会出现。)

LEFT JOIN  tbl_blocco_operativo blocco ON blocco.data = appuntamento.data AND blocco.id_sede = appuntamento.id_sede 
    AND ((blocco.is_fullday = 0 AND blocco.slot = appuntamento.slot) 
         OR blocco.is_fullday = 1)