[英]Pivot query that shows the average amount spent per customer for each month
I'm trying to get better at writing pivot queries by writing one against the Sakila Sample Database that shows the average amount spent per customer for each month.我试图通过针对Sakila 示例数据库编写一个显示每个客户每月花费的平均金额的数据透视查询来更好地编写数据透视查询。 I've got the basic query down, but I'm not sure how to turn it into a pivot query.
我已经完成了基本查询,但我不确定如何将其转换为数据透视查询。
Here's the SQL for that query:这是该查询的 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
And here is the above query with results in my Navicat database development and admin client:这是上面的查询结果在我的 Navicat 数据库开发和管理客户端中:
Anyone know how to convert these results to a pivot query so that the columns from left to right are customer_id, last_name, first_name, Jan, Feb, ...Dec, avg_rental_amt, in either MySQL or SQL Server?任何人都知道如何将这些结果转换为数据透视查询,以便在 MySQL 或 SQL Server 中从左到右的列是 customer_id、last_name、first_name、Jan、Feb、...Dec、avg_rental_amt? I'd like the results to look something like this if possible:
如果可能,我希望结果看起来像这样:
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...
Thanks!谢谢!
Rob抢
You can do conditional aggregation:您可以进行条件聚合:
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
This syntax should work in both SQL Server and MySQL.此语法应适用于 SQL Server 和 MySQL。
Note that this averages together rentals of the same customer over different years - as in your original query.请注意,这是同一客户在不同年份的平均租金 - 如您的原始查询。 This may, or may not be what you want.
这可能是,也可能不是您想要的。 If not, you would need to adapt the conditional expressions for your exact need.
如果没有,您将需要根据您的确切需要调整条件表达式。
You can dynamically manage returning results by applying conditional aggregation您可以通过应用条件聚合来动态管理返回结果
in SQL Server ( Demo ) :在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;
in My SQL ( Demo ):在我的 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.