mySQL:选择行或连接其他表的默认值

lp0sw83n  于 5个月前  发布在  Mysql
关注(0)|答案(1)|浏览(47)

我需要根据不同的参数选择记录-如果一个记录丢失,那么一个默认值。
table在这里

absence_type
+------+--------+
|id    | value  |
+------+--------+
|1     |  null  |
|2     |  null  |
|3     |  20    |
|4     |  null  |
|5     |  null  |
|6     |  null  |
|7     |  null  |
|8     |  null  |
|9     |  null  |
+------+--------+

absences
+-------+-------------+-------------+----------------+------------+
|id     | absenceType | employeeId  | totalDuration  | startDate  |
+-------+-------------+-------------+----------------+------------+
|145    |  9          |    112      |   1            | 2023-01-13 |
|146    |  5          |    406      |   1            | 2023-11-15 |
+-------+-------------+-------------+----------------+------------+

absence_balance
+-------+-------------+-------------+----------------+-------------+
|id     | absenceType | employeeId  | entitlement    | periodYear  | 
+-------+-------------+-------------+----------------+-------------+
|13     |  1          |    112      |   10           |    2022     |
|53     |  1          |    112      |   12           |    2023     |
|54     |  2          |    406      |   5            |    2023     |
+-------+-------------+-------------+----------------+-------------+

字符串
该请求将有一个员工ID,期间年份和一组允许的类型ID,比如'1,2,3,4,9'。
最后,我需要在该periodYear内拥有所有缺勤类型,如果缺勤或余额中缺少特定类型,我仍然需要显示该类型的默认值(absence_type -> value as defaultValue)。因此查询返回:

+--------+-----------+------------+-------------+--------------+---------------+
| typeId | absenceId | employeeId | entitlement | defaultValue | totalDuration | 
+--------+-----------+------------+-------------+--------------+---------------+
|  1     |   null    |    112     |   12        |   20         |       0       |
|  2     |   null    |    112     |   null      |   null       |       0       |
|  3     |   null    |    112     |   null      |   null       |       0       |
|  4     |   null    |    112     |   null      |   null       |       0       |
|  9     |   145     |    112     |   null      |   null       |       1       |
+--------+-----------+------------+-------------+--------------+---------------+


看起来很简单,但是我得到的查询只返回一行,这行在absences表中有一条记录(最后一条)。

select 
  `t`.`id` as `typeId`,
  `a`.`id` as `absenceId`,
  `a`.`employeeId`, 
  `b`.`entitlement`,
  `t`.`value` as `defaultValue`,
  `a`.`totalDuration` 
from `absence_type` as `t` 
left join `absences` as `a` on `a`.`absenceTypeId` = `t`.`id`
left join `absence_balance` as `b` on `b`.`employeeId` = `a`.`employeeId` 
where (`a`.`employeeId` = 112 or `a`.`employeeId` is null) 
and (`b`.`periodYear` = 2023 or `b`.`periodYear` is null)
and (`a`.`startDate` between '2023-01-01' and '2023-12-31' or `a`.`startDate` is null)
and `t`.`id` in (1,2,3,4,9)
group by `a`.`id`

rqenqsqc

rqenqsqc1#

根据@Barmar的建议,这里是一个修改后的查询,它将条件移动到连接条件中:

SELECT
    t.id,
    a.id AS absenceId,
    112 AS employeeId,
    b.entitlement,
    t.value AS defaultValue,
    IFNULL(a.totalDuration, 0) AS totalDuration
FROM absence_type AS t
LEFT JOIN absences AS a ON
    t.id = a.absenceType
    AND a.employeeId = 112
    AND a.startDate BETWEEN '2023-01-01' AND '2023-12-31'
LEFT JOIN absence_balance AS b ON
    t.id = b.absenceType
    AND b.employeeId = 112
    AND b.periodYear = 2023
WHERE t.id IN (1,2,3,4,9);

字符串
当我运行它时,它几乎给出了所需的结果集:

+------+-----------+------------+-------------+--------------+---------------+
| id   | absenceId | employeeId | entitlement | defaultValue | totalDuration |
+------+-----------+------------+-------------+--------------+---------------+
|    1 |      NULL |        112 |          12 |         NULL |             0 |
|    2 |      NULL |        112 |        NULL |         NULL |             0 |
|    3 |      NULL |        112 |        NULL |           20 |             0 |
|    4 |      NULL |        112 |        NULL |         NULL |             0 |
|    9 |       145 |        112 |        NULL |         NULL |             1 |
+------+-----------+------------+-------------+--------------+---------------+


不同之处在于defaultValue--我认为这里正确地显示了类型3。

相关问题