当前位置: 首页 > 面试题库 >

在MySQL中使用函数创建列别名?

曾昂然
2023-03-14
问题内容

我有这张桌子

sales(productid, sales_date)

我想获取过去12个月的每月销售量。

如何在列别名上生成月份名称(无需硬编码)?

我尝试了这个:-

http://sqlfiddle.com/#!2/ee777/9

但是我想要这种格式的结果表

productid   Oct-12  Nov-12  Dec-12  Jan-13  Feb-13  Mar-13  Apr-13  May-13
1           0       0       3       4       2       8       2       11      
2           0       5       6       8       2       0       0       0

我试图使用函数给列别名,DATE_FORMAT(sales_date, '%M')但这是语法错误。

select productid,sum(if(DATE_FORMAT(sales_date,'%Y%m')=
DATE_FORMAT(date_sub(curdate(),interval 12 month),'%Y%m'),1,0)) 
`12 Months Before`,
sum(if(DATE_FORMAT(sales_date,'%Y%m')=
DATE_FORMAT(date_sub(curdate(),interval 11 month),'%Y%m'),1,0)) 
`11 Months Before`,
sum(if(DATE_FORMAT(sales_date,'%Y%m')=
DATE_FORMAT(date_sub(curdate(),interval 10 month),'%Y%m'),1,0)) 
`10 Months Before`,
sum(if(DATE_FORMAT(sales_date,'%Y%m')=
DATE_FORMAT(date_sub(curdate(),interval 9 month),'%Y%m'),1,0)) 
`9 Months Before`,
sum(if(DATE_FORMAT(sales_date,'%Y%m')=
DATE_FORMAT(date_sub(curdate(),interval 8 month),'%Y%m'),1,0)) 
`8 Months Before`,
sum(if(DATE_FORMAT(sales_date,'%Y%m')=
DATE_FORMAT(date_sub(curdate(),interval 7 month),'%Y%m'),1,0)) 
`7 Months Before`,
sum(if(DATE_FORMAT(sales_date,'%Y%m')=
DATE_FORMAT(date_sub(curdate(),interval 6 month),'%Y%m'),1,0)) 
`6 Months Before`,
sum(if(DATE_FORMAT(sales_date,'%Y%m')=
DATE_FORMAT(date_sub(curdate(),interval 5 month),'%Y%m'),1,0)) 
`5 Months Before`,
sum(if(DATE_FORMAT(sales_date,'%Y%m')=
DATE_FORMAT(date_sub(curdate(),interval 4 month),'%Y%m'),1,0)) 
`4 Months Before`,
sum(if(DATE_FORMAT(sales_date,'%Y%m')=
DATE_FORMAT(date_sub(curdate(),interval 3 month),'%Y%m'),1,0)) 
`3 Months Before`,
sum(if(DATE_FORMAT(sales_date,'%Y%m')=
DATE_FORMAT(date_sub(curdate(),interval 2 month),'%Y%m'),1,0)) 
`2 Months Before`,
sum(if(DATE_FORMAT(sales_date,'%Y%m')=
DATE_FORMAT(date_sub(curdate(),interval 1 month),'%Y%m'),1,0)) 
`1 Months Before`
from sales
group by productid;

我如何获得月份和年份的别名(例如:-Oct-12)来代替12 Months Before11 Months Before等等。


问题答案:

MySql没有,PIVOT因此您必须使用conditional SUM()

有两种选择:

  1. 如果周期数是有限的并且事先已知,则可以手动执行
  2. 您可以使用动态SQL即时生成查询,然后执行它

查询option1可能看起来像这样

SELECT productid
      ,SUM(CASE WHEN DATE_FORMAT(sales_date, '%Y%m') = '201210' THEN 1 ELSE 0 END) `Oct12`
      ,SUM(CASE WHEN DATE_FORMAT(sales_date, '%Y%m') = '201211' THEN 1 ELSE 0 END) `Nov12`      
      ,SUM(CASE WHEN DATE_FORMAT(sales_date, '%Y%m') = '201212' THEN 1 ELSE 0 END) `Dec12`
      ,SUM(CASE WHEN DATE_FORMAT(sales_date, '%Y%m') = '201301' THEN 1 ELSE 0 END) `Jan13`
      ,SUM(CASE WHEN DATE_FORMAT(sales_date, '%Y%m') = '201302' THEN 1 ELSE 0 END) `Feb13`      
      ,SUM(CASE WHEN DATE_FORMAT(sales_date, '%Y%m') = '201303' THEN 1 ELSE 0 END) `Mar13`
      ,SUM(CASE WHEN DATE_FORMAT(sales_date, '%Y%m') = '201304' THEN 1 ELSE 0 END) `Apr13`
      ,SUM(CASE WHEN DATE_FORMAT(sales_date, '%Y%m') = '201305' THEN 1 ELSE 0 END) `May13`      
      ,SUM(CASE WHEN DATE_FORMAT(sales_date, '%Y%m') = '201306' THEN 1 ELSE 0 END) `Jun13`
 FROM sales
WHERE sales_date BETWEEN '2012-10-01' AND '2013-06-30'
GROUP BY productid

样本输出:

| PRODUCTID | OCT12 | NOV12 | DEC12 | JAN13 | 2月13日| MAR13 | APR13 | 5月13日| 13月|
-------------------------------------------------- -----------------------------------
| 1 | 0 | 0 | 0 | 1 | 1 | 0 | 0 | 2 | 1 |
| 2 | 1 | 1 | 1 | 0 | 0 | 1 | 1 | 1 | 2 |

这是 SQLFiddle 演示

现在是使用动态SQL(PREPAREEXECUTE)的 选项2的版本

SELECT
  GROUP_CONCAT(DISTINCT
    CONCAT(
      'SUM(CASE WHEN DATE_FORMAT(sales_date, ''%Y%m'') = ''',
      DATE_FORMAT(period, '%Y%m'), ''' THEN 1 ELSE 0 END) `', DATE_FORMAT(period, '%b%y'), '`'
    )
  ) INTO @sql
FROM
(
    SELECT DATE_FORMAT(sales_date, '%Y-%m-01') period
      FROM sales
     WHERE sales_date BETWEEN DATE_FORMAT(CURDATE() - INTERVAL 11 MONTH, '%Y-%m-01') AND CURDATE()
     GROUP BY DATE_FORMAT(sales_date, '%Y-%m-01')
) s;

SET @sql = CONCAT
('SELECT productid, ', @sql, ' 
    FROM sales
   WHERE sales_date BETWEEN DATE_FORMAT(CURDATE() - INTERVAL 11 MONTH, ''%Y-%m-01'') AND CURDATE()
   GROUP BY productid'
);

PREPARE stmt FROM @sql;
EXECUTE stmt;
DEALLOCATE PREPARE stmt;

输出是相同的。

| PRODUCTID | 7月| AUG12 | SEP12 | OCT12 | NOV12 | DEC12 | JAN13 | 2月13日| MAR13 | APR13 | 5月13日| 13月|
-------------------------------------------------- -------------------------------------------------- ---------
| 1 | 1 | 2 | 1 | 0 | 0 | 0 | 1 | 1 | 0 | 0 | 2 | 1 |
| 2 | 0 | 0 | 0 | 1 | 1 | 1 | 0 | 0 | 1 | 1 | 1 | 2 |

这是 SQLFiddle 演示



 类似资料:
  • 我有一个数据框,如: 我需要为每个列应用一些函数,并在这个数据帧中创建具有特殊名称的新列。 所以我需要根据列和(如name)乘以两个额外的列,名称为和由两个。是否可以使用或其他结构来完成此操作?

  • 问题内容: 我正在将MS Access应用程序(已将表链接到MSSQL Server)迁移到MySQL。 作为克服某些MSAccess表命名问题的方法,我正在寻找一种解决方案以添加一个MySQL表别名,该别名将指向MySQL数据库中的现有表。理想情况下,我想在mysql中创建别名“ dbo_customers”,该别名也指向mysql中的customers表。 需要明确的是,我 不 希望别名这样的

  • 问题内容: 我想以这样的方式串联列名:列名的第一部分是一个字符串,第二部分是一个数字,这是另一个查询的结果。 例如: 能以某种方式做到这一点。这样,它不会给我带来错误,但是我没有得到预期的结果,并且似乎串联不起作用。 问题答案: 我之前曾说过无法做到这一点,但是我错了。我本人最终需要这样的东西,所以我环顾四周,发现服务器端准备好的语句使您可以从字符串构建和执行任意SQL语句。 这是我只是为了证明这

  • 本文向大家介绍创建一个MySQL函数并在列中找到平均值,包括了创建一个MySQL函数并在列中找到平均值的使用技巧和注意事项,需要的朋友参考一下 让我们首先创建一个表- 使用插入命令在表中插入一些记录- 使用select语句显示表中的所有记录- 这将产生以下输出- 以下是创建返回平均值的函数的查询- 现在您可以使用select语句调用该函数- 这将产生以下输出-

  • 问题内容: 以root用户身份登录后,在 MySQL 命令行客户端中键入: 现在在 Java中 ,我使用驱动程序使用admin userid成功连接到数据库。 为什么插入命令有效,但授权命令却无法通过Java工作? 请帮忙。 问题答案: 在这里,您只能执行MySQL查询,但 不是MySQL查询,它只是MySQL的命令。

  • 问题内容: 我需要创建一个视图,该视图具有一个名为row_num的列,将在其中插入行号,就像在普通表中自动递增一样。 假设我有这个普通表: 等等… 我要创建的视图是: 等等… 我可以通过一次选择生成row_num: 但是我的问题是将上面的查询与创建视图的查询结合起来。这是我正在尝试的组合查询: 我收到以下错误:#1351-视图的SELECT包含变量或参数 我知道我不能在带有视图的选择内使用选择,但