首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> 更多程式語言 >> 程式設計綜合問答

SQL 高效統計:依 ID、Time 分組判斷 Pos 1-4 完整且 Result 全 True 的比例

     編輯:程式設計綜合問答

資料樣本

ID   Time       Pos  Result
1    15:00:1    1    true
1    15:00:1    2    true
1    15:00:1    3    true
1    15:00:1    4    true   <-- 完整組,全 true
1    15:00:2    1    true
1    15:00:2    2    true   <-- 不完整組 (缺 3,4)
3    15:00:1    1    true
3    15:00:1    2    false  <-- 完整組,含 false
3    15:00:1    3    true
3    15:00:1    4    true

需求邏輯

  1. 以 ID, Time 為唯一鍵分組。
  2. 該群組必須包含 Pos = 1,2,3,4 四筆資料,始視為「完整組」。
  3. 完整組中 Result 全為 true → 計為 true;否則 false。
  4. 不完整組 (如 15:00:2) → 標記為「無效」,不計入統計。
  5. 同一 ID 有多組完整資料時,**取最新 (Time 最大) 那一組**判斷。
  6. 最終輸出:各 ID 的 True 比例 (True 組數 / 完整組總數)。

高效 SQL 寫法 (通用標準 SQL)

WITH CompleteGroups AS (
    SELECT
        ID,
        Time,
        COUNT(DISTINCT Pos) AS pos_cnt,
        MIN(CASE WHEN Result = 'true' THEN 1 ELSE 0 END) AS all_true
    FROM YourTable
    WHERE Pos IN (1,2,3,4)
    GROUP BY ID, Time
    HAVING COUNT(DISTINCT Pos) = 4
),
LatestPerID AS (
    SELECT
        ID,
        all_true,
        ROW_NUMBER() OVER (PARTITION BY ID ORDER BY Time DESC) AS rn
    FROM CompleteGroups
)
SELECT
    ID,
    CASE WHEN SUM(all_true) > 0 THEN 1.0 * SUM(all_true) / COUNT(*) ELSE 0 END AS true_ratio
FROM LatestPerID
WHERE rn = 1
GROUP BY ID;

關鍵點解析

  • CTE 分層:先篩選完整組,再取各 ID 最新一筆,邏輯清晰、效能佳。
  • MIN(CASE...):若群組內有任何 false,MIN 為 0,等同「全 true」判斷。
  • ROW_NUMBER():避免自我連接或子查詢,單掃描取最新時間。
  • 索引建議:CREATE INDEX idx_id_time_pos ON YourTable(ID, Time, Pos); 大幅加速分組與排序。

MySQL 8.0+ / PostgreSQL / SQL Server 通用

上述語法支援所有支援 CTE 與視窗函數的現代資料庫。若為 MySQL 5.7,需改用變數模擬 ROW_NUMBER 或子查詢取 MAX(Time)。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved