簡體   English   中英

顯示每個客戶每月平均花費的樞軸查詢

[英]Pivot query that shows the average amount spent per customer for each month

我試圖通過針對Sakila 示例數據庫編寫一個顯示每個客戶每月花費的平均金額的數據透視查詢來更好地編寫數據透視查詢。 我已經完成了基本查詢,但我不確定如何將其轉換為數據透視查詢。

這是該查詢的 SQL:

SELECT
    payment.amount AS amount,
    customer.customer_id AS customer_id,
    customer.last_name AS last_name, 
    customer.first_name AS first_name,
    FORMAT ( rental.rental_date, 'MMM' ) _Month,
    avg(amount) over ( PARTITION BY customer.customer_id ) avg_rental_amt
FROM
    customer INNER JOIN
 rental
 ON customer.customer_id = rental.customer_id INNER JOIN
 payment
 ON payment.rental_id = rental.rental_id AND
    payment.customer_id = customer.customer_id

這是上面的查詢結果在我的 Navicat 數據庫開發和管理客戶端中:

顯示每個客戶每月平均花費的查詢

任何人都知道如何將這些結果轉換為數據透視查詢,以便在 MySQL 或 SQL Server 中從左到右的列是 customer_id、last_name、first_name、Jan、Feb、...Dec、avg_rental_amt? 如果可能,我希望結果看起來像這樣:

customer_id last_name   first_name  Jan  Feb...Dec    avg_rental_amt
505         ABNEY       RAFAEL      4.9  2.9   3.4    4.65
504         ADAM        NATHANIEL   5.3  4.4   5.2    4.77
36          ADAMS       KATHLEEN    .9  .9     3.1    3.43
etc...

謝謝!

您可以進行條件聚合:

SELECT c.customer_id, c.last_name, c.first_name,
    AVG(CASE WHEN MONTH(r.rental_date) =  1 THEN p.amount END) as avg_rental_january,
    AVG(CASE WHEN MONTH(r.rental_date) =  2 THEN p.amount END) as avg_rental_feb,
    ...
    AVG(CASE WHEN MONTH(r.rental_date) = 12 THEN p.amount END) as avg_rental_december,
    AVG(p.amount) avg_rental
FROM customer c
INNER JOIN rental r ON c.customer_id = r.customer_id 
INNER JOIN payment p ON p.rental_id = r.rental_id AND p.customer_id = c.customer_id
GROUP BY c.customer_id, c.last_name, c.first_name

此語法應適用於 SQL Server 和 MySQL。

請注意,這是同一客戶在不同年份的平均租金 - 如您的原始查詢。 這可能是,也可能不是您想要的。 如果沒有,您將需要根據您的確切需要調整條件表達式。

您可以通過應用條件聚合來動態管理返回結果

SQL Server( 演示)中:

DECLARE @cols  AS NVARCHAR(MAX),  @query AS NVARCHAR(MAX);
WITH t AS
(
 SELECT 1 AS n UNION ALL
 SELECT n + 1 FROM t WHERE n + 1 <= 12
)
SELECT @cols = STRING_AGG(CONCAT('AVG(CASE WHEN MONTH(r.rental_date)=',n,
                                         ' THEN r.amount END) "',
                                         FORMAT ( DATEADD( month , n , -1 ), 'MMM' ),
                                         '"'), ',') 
  FROM t;

SET  @query = 
       CONCAT(
              'SELECT c.customer_id AS customer_id,' , @cols , 
              '       , AVG(r.amount) AS avg_rental_amt ',
              '  FROM customer c
                 JOIN rental r
                   ON c.customer_id = r.customer_id
                 JOIN payment p
                   ON p.rental_id = r.rental_id
                  AND p.customer_id = c.customer_id
                GROUP BY c.customer_id, c.last_name, c.first_name');

EXEC sp_executesql @query;

我的 SQL( 演示)中:

SET @query = NULL;
SET @cols = NULL;

SELECT GROUP_CONCAT(                 
             CONCAT(
                    'AVG(CASE WHEN MONTH(r.rental_date)=', n,
                            ' THEN r.amount END) AS "',
                           DATE_FORMAT(CONCAT('0000-',LPAD(n,2,0),'-00'), '%b'),
                           '"'
                    )
       )
  INTO @cols
  FROM
  (
   SELECT @n := @n + 1 AS n
     FROM information_schema.tables 
     JOIN (SELECT @n := 0) AS iter ) nn
  WHERE n <= 12;

SET  @query = 
       CONCAT(
              'SELECT c.customer_id AS customer_id,' , @cols , 
              '       , AVG(r.amount) AS avg_rental_amt ',
              '  FROM customer c
                 JOIN rental r
                   ON c.customer_id = r.customer_id
                 JOIN payment p
                   ON p.rental_id = r.rental_id
                  AND p.customer_id = c.customer_id
                GROUP BY c.customer_id, c.last_name, c.first_name');

PREPARE stmt FROM @query;
EXECUTE stmt;
DEALLOCATE PREPARE stmt;

暫無
暫無

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

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