简体   繁体   English

显示每个客户每月平均花费的枢轴查询

[英]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.

相关问题 每个顾客在餐厅消费的总金额是多少? 无法看到不同的 customer_id .. 仅显示所有金额的一个相同 id - What is the total amount each customer spent at the restaurant? Not able to see different customer_id.. shows only one same id for all amounts 计算特定月份mysql的平均支出(支出/人) - Calculating average spending (amount spent/person) in a particular month mysql 每个月的平均客户支出和每个月的订购商品数量 - Average customer spending at each month and number of ordered items at each month MariaDB:Select 每个项目每月平均(数据透视表) - MariaDB: Select average per month per item (Pivot table) 我正在使用3表联接计算每个客户在mysql上花费的总金额 - I am calculating total amount spent per customer in mysql, using join with 3 tables 查询以获取每个客户的每周平均支出 - Query to get weekly average spending each customer 计算员工上个月在工作场所每天所花费的平均小时数 - calculate the average number of hours per day that the employee spent on the workplace for the previous month 按客户分组并按月份列透视查询显示的Mysql销售表 - Mysql sales table grouped by customer and displayed by month columns pivot query SQL 平均每天花费的钱 - SQL average money spent per day SUM() 子查询每个客户花费的总金额 - SUM() subquery for total money spent for each customer
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM