簡體   English   中英

用於返回計數和最大值的 SQL 語句

[英]A SQL statement to return a count and a max

我使用 Spring 引導和 Hibernate。 目前我對數據庫有 3 個單獨的請求:

  1. 從表 aaa 中獲取所有特定(帶有一些 WHERE 條件)數據
  2. 從表 bbb 中獲取所有特定(帶有一些 WHERE 條件)數據
  3. 從點 1 和點 2 獲取具有相同條件的 WHERE 子句找到的最大記錄日期。

聲明#1

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

聲明#2

SELECT count(b.id) as dateTo
from (
        SELECT b.date_to
        FROM bbb b
        WHERE tw.warehouse.id = :warehouseId
            AND tw.status = 'AVAILABLE'
    ) allDates

聲明#3

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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM