如何在MySQL中高效地将动态行转换为列
我正在寻找一种在SQL server中将行转换为列的有效方法,我听说PIVOT不是很快,我需要处理大量记录 我试着遵循这一点,但仍然没有解决我下面的例子 这是我的例子:(更新) 这是我的预期结果:如何在MySQL中高效地将动态行转换为列,mysql,sql,Mysql,Sql,我正在寻找一种在SQL server中将行转换为列的有效方法,我听说PIVOT不是很快,我需要处理大量记录 我试着遵循这一点,但仍然没有解决我下面的例子 这是我的例子:(更新) 这是我的预期结果: --------------------------------------------------------------------- | FirstName |Amount| PostalCode | LastName | AccountNumber | -----------
---------------------------------------------------------------------
| FirstName |Amount| PostalCode | LastName | AccountNumber |
---------------------------------------------------------------------
| John | 2.4 | ZH1E4A | Fork | 857685 |
| Donny | 2.7 | ZH1E4C | Yen | 857686 |
---------------------------------------------------------------------
如何生成结果?您需要根据它们的关联键对它们进行分组:
WITH
indata(Id,Value,ColumnName) AS (
SELECT 1,'John' ,'FirstName'
UNION ALL SELECT 2,'2.4' ,'Amount'
UNION ALL SELECT 3,'ZH1E4A' ,'PostalCode'
UNION ALL SELECT 4,'Fork' ,'LastName'
UNION ALL SELECT 5,'857685' ,'AccountNumber'
UNION ALL SELECT 6,'Donny' ,'FirstName'
UNION ALL SELECT 7,'2.7' ,'Amount'
UNION ALL SELECT 8,'ZH1E4C' ,'PostalCode'
UNION ALL SELECT 9,'Yen' ,'LastName'
UNION ALL SELECT 10,'857686','AccountNumber'
)
,
-- need to get a grouping column, one that
-- changes every time we encounter a 'FirstName
-- add a counter that is at 1 for FirstName
-- otherwise at 0, and build a running sum...
w_session_id AS (
SELECT
SUM(CASE ColumnName WHEN 'FirstName' THEN 1 END)
OVER(ORDER BY id) AS sessid
, *
FROM indata
)
-- now un-pivot manually
SELECT
sessid AS id
, MAX(CASE ColumnName WHEN 'FirstName' THEN value END) AS FirstName
, MAX(CASE ColumnName WHEN 'Amount' THEN value END) AS Amount
, MAX(CASE ColumnName WHEN 'PostalCode' THEN value END) AS PostalCode
, MAX(CASE ColumnName WHEN 'LastName' THEN value END) AS LastName
, MAX(CASE ColumnName WHEN 'AccountNumber' THEN value END) AS AccountNumber
FROM w_session_id
GROUP BY sessid;
-- out id | FirstName | Amount | PostalCode | LastName | AccountNumber
-- out ----+-----------+--------+------------+----------+---------------
-- out 1 | John | 2.4 | ZH1E4A | Fork | 857685
-- out 2 | Donny | 2.7 | ZH1E4C | Yen | 857686
GROUP BY
强制每个唯一的submission\u id
都有一行,MAX
为特定的组键选择表达式的最后代值(假定为单数,因此聚合类型不重要),最后,CASE
通过ColumnName
过滤值
,您需要根据它们的关联键对它们进行分组:
GROUP BY
强制每个唯一的submission\u id
都有一行,MAX
为特定的组键选择表达式的最后代值(假定为单数,因此聚合类型不重要),最后,CASE
通过ColumnName
过滤值,你提到的问题到底有多大帮助?你如何关联LastName
=Fork
与FirstName
=John
而不是FirstName
=Donny
?此外,您还说有问题的SQL server
,但标记了mysql
您的问题有mysql
标记,PIVOT
操作符在MS SQL
中定义。上面提到的pivot函数与MySQL无关MySQL有没有这样的功能,慢还是快?你能在表示层做吗?首先弄清楚你使用的是哪种RDBMS你提到的问题到底有多大帮助?你如何将LastName
=Fork
与FirstName
=John
关联,而不是与FirstName
=Donny
关联?此外,您还说有问题的SQL server
,但标记了mysql
您的问题有mysql
标记,PIVOT
操作符在MS SQL
中定义。上面提到的pivot函数与MySQL无关MySQL有没有这样的功能,慢还是快?您可以在表示层中执行此操作吗?首先确定您使用的是哪种RDBMS
WITH
indata(Id,Value,ColumnName) AS (
SELECT 1,'John' ,'FirstName'
UNION ALL SELECT 2,'2.4' ,'Amount'
UNION ALL SELECT 3,'ZH1E4A' ,'PostalCode'
UNION ALL SELECT 4,'Fork' ,'LastName'
UNION ALL SELECT 5,'857685' ,'AccountNumber'
UNION ALL SELECT 6,'Donny' ,'FirstName'
UNION ALL SELECT 7,'2.7' ,'Amount'
UNION ALL SELECT 8,'ZH1E4C' ,'PostalCode'
UNION ALL SELECT 9,'Yen' ,'LastName'
UNION ALL SELECT 10,'857686','AccountNumber'
)
,
-- need to get a grouping column, one that
-- changes every time we encounter a 'FirstName
-- add a counter that is at 1 for FirstName
-- otherwise at 0, and build a running sum...
w_session_id AS (
SELECT
SUM(CASE ColumnName WHEN 'FirstName' THEN 1 END)
OVER(ORDER BY id) AS sessid
, *
FROM indata
)
-- now un-pivot manually
SELECT
sessid AS id
, MAX(CASE ColumnName WHEN 'FirstName' THEN value END) AS FirstName
, MAX(CASE ColumnName WHEN 'Amount' THEN value END) AS Amount
, MAX(CASE ColumnName WHEN 'PostalCode' THEN value END) AS PostalCode
, MAX(CASE ColumnName WHEN 'LastName' THEN value END) AS LastName
, MAX(CASE ColumnName WHEN 'AccountNumber' THEN value END) AS AccountNumber
FROM w_session_id
GROUP BY sessid;
-- out id | FirstName | Amount | PostalCode | LastName | AccountNumber
-- out ----+-----------+--------+------------+----------+---------------
-- out 1 | John | 2.4 | ZH1E4A | Fork | 857685
-- out 2 | Donny | 2.7 | ZH1E4C | Yen | 857686
SELECT
MAX(CASE ColumnName WHEN 'FirstName' THEN Value END) AS FirstName,
MAX(CASE ColumnName WHEN 'Amount' THEN Value END) AS Amount,
MAX(CASE ColumnName WHEN 'PostalCode' THEN Value END) AS PostalCode,
MAX(CASE ColumnName WHEN 'LastName' THEN Value END) AS LastName,
MAX(CASE ColumnName WHEN 'AccountNumber' THEN Value END) AS AccountNumber
FROM table
GROUP BY submission_id
;