Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/mysql/71.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
如何在MySQL中高效地将动态行转换为列_Mysql_Sql - Fatal编程技术网

如何在MySQL中高效地将动态行转换为列

如何在MySQL中高效地将动态行转换为列,mysql,sql,Mysql,Sql,我正在寻找一种在SQL server中将行转换为列的有效方法,我听说PIVOT不是很快,我需要处理大量记录 我试着遵循这一点,但仍然没有解决我下面的例子 这是我的例子:(更新) 这是我的预期结果: --------------------------------------------------------------------- | FirstName |Amount| PostalCode | LastName | AccountNumber | -----------

我正在寻找一种在SQL server中将行转换为列的有效方法,我听说PIVOT不是很快,我需要处理大量记录

我试着遵循这一点,但仍然没有解决我下面的例子

这是我的例子:(更新)

这是我的预期结果:

---------------------------------------------------------------------
| 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
;