[英]A SQL statement to return a count and a max
我使用 Spring 引导和 Hibernate。 目前我对数据库有 3 个单独的请求:
SELECT count(a.id) as dateTo
from (
SELECT a.date_to
FROM aaa a
JOIN ramp r on a.ramp_id = r.id
JOIN warehouse w on r.warehouse_id = r.warehouse_id
WHERE w.id = 222
AND a.date_from >= '2022-08-20T00:00'
) allDates
SELECT count(b.id) as dateTo
from (
SELECT b.date_to
FROM bbb b
WHERE tw.warehouse.id = :warehouseId
AND tw.status = 'AVAILABLE'
) allDates
SELECT MAX(date_to) as dateTo
from (
SELECT a.date_to
FROM aaa a
JOIN ramp r on a.ramp_id = r.id
JOIN warehouse w on r.warehouse_id = r.warehouse_id
WHERE w.id = 222
AND a.date_from >= '2022-08-20T00:00'
UNION
SELECT b.valid_to as date_to
FROM bbb b
WHERE b.warehouse_id = 222
AND tw.status = 'AVAILABLE'
) allDates
是否有可能用一个语句来完成所有这一切? 我使用 MySql 5.7,所以 CTE 不可用。
我在 Spring 中的代码:
final long numberOfa = ...
final long numberOfB = ...
final LocalDate maxDate = ...
预期结果:
final MyObjectWithAllThreeValues myObject = repository.getAllDataWithOneQuery
您可以在子查询中存储一个标志(称为“ which_tab ”),然后在SUM
聚合 function 中使用CASE
表达式来计算行数。
SELECT MAX(date_to) AS dateTo,
SUM(CASE WHEN which_tab = 'a' THEN 1 END) AS count_a_id,
SUM(CASE WHEN which_tab = 'b' THEN 1 END) AS count_b_id
from (
SELECT 'a' AS which_tab, a.date_to
FROM aaa a
JOIN ramp r on a.ramp_id = r.id
JOIN warehouse w on r.warehouse_id = r.warehouse_id
WHERE w.id = 222
AND a.date_from >= '2022-08-20T00:00'
UNION ALL
SELECT 'b' AS which_tab, b.valid_to AS date_to
FROM bbb b
WHERE b.warehouse_id = 222
AND tw.status = 'AVAILABLE'
) allDates
注意:如果您应用UNION
的两个子查询中的行不重叠,则最好使用UNION ALL
,因为它可以避免额外的不必要的聚合。
所有查询都返回一行,因为您在没有任何GROUP BY
的情况下聚合了所有行。 因此,您可以进行两种聚合,然后交叉连接两个结果行:
SELECT
a_agg.cnt AS count_a,
b_agg.cnt AS count_b,
GREATEST(a.max_date, b.max_date) AS max_date
FROM
(
SELECT COUNT(*) AS cnt, MAX(a.date_to) AS max_date
FROM aaa a
JOIN ramp r ON r.id = a.ramp_id
JOIN warehouse w ON w.warehouse_id = r.warehouse_id
WHERE w.id = 222
AND a.date_from >= TIMESTAMP '2022-08-20 00:00:00'
) a_agg
CROSS JOIN
(
SELECT COUNT(*) AS cnt, MAX(b.date_to) AS max_date
FROM bbb b
WHERE b.warehouse.id = :warehouseId
AND b.status = 'AVAILABLE'
) b_agg;
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.