首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫

MySQL 查詢指定時間段內未銷售商品:三表關聯 NOT IN 實戰

     編輯:MySQL 資料庫相關知識

業務需求:找出發布一個月內**從未售出**的商品。涉及三表:

  • zd_product:商品表,主鍵 zp_id,發布時間 inputtime
  • zd_order:訂單表,主鍵 zo_id,外鍵 zp_id,完成時間 zo_voer_time
  • zd_ord_pro:訂單商品關聯表,zo_id、zp_id

解題思路

  1. 先查詢「一個月內**已售出**的商品 ID」集合
  2. 商品表中排除該集合(NOT IN)
  3. 輸出符合條件的商品資訊

核心 SQL

SELECT * 
FROM zd_product a1
LEFT JOIN zd_ord_pro a3 ON a1.zp_id = a3.zp_id
WHERE a1.zp_id NOT IN (
    SELECT zp_id 
    FROM zd_order a2 
    WHERE a2.zo_voer_time > a1.inputtime 
      AND a2.zo_voer_time < a1.inputtime + INTERVAL 30 DAY
);

關鍵點解析

  • 相關子查詢:子查詢引用外層 a1.inputtime,實現「每個商品以自己的發布時間為基準,向前 30 天」的動態窗口。
  • 時間運算:使用 INTERVAL 30 DAY 而非數值相加,避免時間戳/日期類型混淆。
  • LEFT JOIN zd_ord_pro:保留無關聯訂單的商品(即從未被訂單引用的商品),若改 INNER JOIN 會漏掉這類商品。
  • NOT IN 陷阱:若子查詢結果含 NULL,整個 NOT IN 返回空集。本案 zp_id 為主鍵/外鍵非空,安全。通用寫法建議改 NOT EXISTS:
WHERE NOT EXISTS (
    SELECT 1 FROM zd_order a2 
    WHERE a2.zp_id = a1.zp_id
      AND a2.zo_voer_time > a1.inputtime
      AND a2.zo_voer_time < a1.inputtime + INTERVAL 30 DAY
)

效能優化建議

  1. zd_order(zo_voer_time, zp_id) 建立聯合索引,支援時間範圍+商品 ID 查詢
  2. zd_product(inputtime) 建立索引,加速發布時間篩選
  3. 大數據量下考慮分區表或物化視圖預計算「近 30 天銷售商品」
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved