簡體   English   中英

如何選擇多列的行,其中一列包含不同的值和 GROUP BY 日期?

[英]How can I SELECT rows with multiple columns where a column includes different values and GROUP BY date?

我有一個 MySQL db company有表department (表中的department是銷售和營銷),表campaign ,表product 以及兩個連接表department_campaigndepartment_product

每個活動每天有 3 次促銷活動。 每日促銷的結果存儲在表promotion_result 例如,如果 Campaign_id = 1,請查看行:

    "created"          "campaign_id"    "promotion"   "product_id"
2020-02-06 09:42:59          1               a             281
2020-02-06 13:35:22          1               b            (null)
2020-02-06 17:55:43          1               c            (null)
2020-02-07 14:42:59          1               a             350
2020-02-07 14:42:59          1               b             350
2020-02-07 14:42:59          1               c            (null)
2020-02-08 14:42:59          1               a            (null)
2020-02-08 14:42:59          1               b            (null)
2020-02-08 14:42:59          1               c            (null)

在“product_id” column是在“創建”時間隨促銷一起出售的產品。

我想有一個查詢來獲取一個列表,我可以在其中看到每天哪個部門銷售的促銷產品。 如果一天沒有售出產品,那么我希望那天只看到一行(空)。 我在 mysql 中嘗試了這個查詢:

SELECT DATE(pr.created) AS created, pr.campaign_id AS campaign, pr.promotion AS promotion, pr.product_id AS product
FROM department AS dept
          LEFT JOIN department_campaign AS dc ON dc.department_id = dept.id
          LEFT JOIN department_products AS dp ON dp.department_id = dept.id
          LEFT JOIN promotion_result AS pr ON dc.campaign_id = pr.campaign_id
          WHERE dept.id = 2 AND pr.campaign_id = 1
          GROUP BY DATE(pr.created), product_id, promotion
          ORDER BY DATE(pr.created) ASC, promotion ASC

結果:

   "created"    "campaign"   "promotion"    "product"
  2020-02-06         1            a            281
  2020-02-06         1            b           (null)
  2020-02-06         1            c           (null)
  2020-02-07         1            a            350
  2020-02-07         1            b            350
  2020-02-07         1            c           (null)
  2020-02-08         1            a           (null)
  2020-02-08         1            b           (null)
  2020-02-08         1            c           (null) 

如果我將AND dp.product_id = pr.product_id添加到where那么我只會得到產品銷售的日期,而不是銷售的日期:

"created"    "campaign"  "promotion"    "product"
2020-02-06       1            a            281
2020-02-07       1            a            350
2020-02-07       1            b            350

什么期望:

   "created"    "campaign"   "promotion"    "product"
  2020-02-06         1            a            281
  2020-02-07         1            a            350
  2020-02-07         1            b            350
  2020-02-08         1          (null)        (null)

在這種情況下,我可以看到每天每個促銷活動的銷售產品以及沒有銷售的日子(“產品”=(空)和“促銷”=(空))

有人可以幫我解決這個問題嗎?

以下是有效查詢的示例:

SELECT DISTINCT DATE(pr.created) created
              , pr.campaign_id campaign
              , pr.promotion 
              , pr.product_id product
           FROM department d
           LEFT 
           JOIN department_campaign dc 
             ON dc.department_id = d.id
           LEFT 
           JOIN department_products dp 
             ON dp.department_id = dept.id
           LEFT 
           JOIN promotion_result pr 
             ON pr.campaign_id = dc.campaign_id 
            AND pr.product_id = dp.product_id  
            AND pr.campaign_id = 1
          WHERE d.id = 2 
          ORDER 
             BY DATE(pr.created) ASC, promotion ASC

MySQL 沒有遞歸功能。 給定的答案適用於 PostgreSQL 數據庫。

請參閱: https : //stackoverflow.com/a/3538926/10086603在表格中生成日期並以類似方式右連接的答案。

在離開加入promotion_result 時添加條件而不是在“where”中。

生成系列有助於填補缺失的日期。 (PostgreSQL)

SELECT DATE(pr.created) AS created,
       pr.campaign_id AS campaign,
       pr.promotion AS promotion,
       pr.product_id AS product
FROM department AS dept
LEFT JOIN department_campaign AS dc ON dc.department_id = dept.id
LEFT JOIN department_products AS dp ON dp.department_id = dept.id
LEFT JOIN promotion_result AS pr ON dc.campaign_id = pr.campaign_id
AND dp.product_id = pr.product_id
AND pr.campaign_id = 1
RIGHT JOIN
  (SELECT generate_series(TIMESTAMP '2020-02-01' , TIMESTAMP '2020-02-01' + interval '1 month - 1 day' , interval '1 day')::date as day) d ON pr.created = d.day
WHERE dept.id = 2
GROUP BY DATE(pr.created),
         product_id,
         promotion
ORDER BY DATE(pr.created) ASC, promotion ASC

我找到了一個使用SELECT DISTINCTUNION來獲得預期結果的解決方案。 我分享它,以便它也可以幫助其他人:

SELECT DISTINCT DATE(pr.created) AS created, pr.campaign_id AS campaign, pr.promotion AS promotion, pr.product_id AS product
FROM department AS dept
LEFT JOIN department_campaign AS dc ON dc.department_id = dept.id
LEFT JOIN department_products AS dp ON dp.department_id = dept.id
LEFT JOIN promotion_result AS pr ON pr.product_id = dp.product_id
WHERE dept.id = 2 AND pr.campaign_id = 1
UNION
SELECT DISTINCT DATE(pr.created) AS created, pr.campaign_id AS campaign, NULL, pr.product_id AS product
FROM department AS dept
LEFT JOIN department_campaign AS dc ON dc.department_id = dept.id
LEFT JOIN department_products AS dp ON dp.department_id = dept.id
LEFT JOIN promotion_result AS pr ON dc.campaign_id = pr.campaign_id
WHERE dept.id = 2 AND pr.campaign_id = 1 AND pr.product_id is NULL AND DATE(pr.created) NOT IN (SELECT DISTINCT DATE(pr1.created)
FROM department AS dept1
LEFT JOIN department_campaign AS dc1 ON dc1.department_id = dept1.id
LEFT JOIN department_products AS dp1 ON dp1.department_id = dept1.id
LEFT JOIN promotion_result AS pr1 ON pr1.product_id = dp1.product_id
WHERE dept1.id = 2 AND pr1.campaign_id = 1)
ORDER BY created ASC, promotion ASC

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

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