首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 數據庫知識 >  >> MySQL 資料庫 >> MySQL 綜合教學

MySQL 查詢「發布一個月內未售出商品」的高效寫法

     編輯:MySQL 綜合教學

業務場景

三張表:

  • zd_product:商品表 (zp_id PK, inputtime 發布時間)
  • zd_order:訂單表 (zo_id PK, zp_id FK, zo_voer_time 完成時間)
  • zd_ord_pro:訂單商品關聯表 (zo_id FK, zp_id FK)

需求:找出發布後 30 天內 完全無銷售記錄 的商品。

解題思路:反向排除法

  1. 先查「30 天內有銷售」的商品 ID 集合
  2. 再從商品表排除該集合
  3. 最後關聯所需顯示字段

優化 SQL

SELECT p.*
FROM zd_product p
WHERE p.zp_id NOT IN (
    SELECT DISTINCT o.zp_id
    FROM zd_order o
    JOIN zd_ord_pro op ON o.zo_id = op.zo_id
    WHERE o.zo_voer_time > p.inputtime
      AND o.zo_voer_time < DATE_ADD(p.inputtime, INTERVAL 30 DAY)
);

關鍵點解析

  • 使用 DATE_ADD 做日期運算,避免時間戳轉換效能損耗
  • DISTINCT 減少子查詢返回行數
  • NOT IN 邏輯清晰,注意子查詢結果含 NULL 時語義變化(此場景 zp_id 非空安全)
  • 確保 zd_order.zo_voer_time、zd_product.inputtime 有索引

替代寫法:LEFT JOIN + IS NULL

SELECT p.*
FROM zd_product p
LEFT JOIN (
    SELECT DISTINCT o.zp_id
    FROM zd_order o
    JOIN zd_ord_pro op ON o.zo_id = op.zo_id
    WHERE o.zo_voer_time > p.inputtime
      AND o.zo_voer_time < DATE_ADD(p.inputtime, INTERVAL 30 DAY)
) sold ON p.zp_id = sold.zp_id
WHERE sold.zp_id IS NULL;

在某些版本中 JOIN 寫法執行計劃更優,建議 EXPLAIN 對比。

提示:原文 SQL 未驗證,上述為重構優化版,實際上線前請在測試庫驗證執行計劃與結果正確性。
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved