我有一个包含几列的表,我想要SELECT:
SELECT
SELECT his_name , her_name, other_name FROM foo;
Bu,我想将结果全部合并到一个列中。例如,我可以使用UNION ALLas
UNION ALL
SELECT her_name AS name FROM foo UNION ALL SELECT his_name AS name FROM foo UNION ALL SELECT other_name AS name FROM foo
有没有更优雅的方法来做这个操作?
我不清楚什么是“更优雅的方式”。
Oracle 你可以使用下面的语句将列变成行
select all_name from foo unpivot (all_name for col_name in ( his_name, her_name, other_name));
这是select语句的语法图
SELECT [ALL | DISTINCT | DISTINCTROW ] [HIGH_PRIORITY] [STRAIGHT_JOIN] [SQL_SMALL_RESULT] [SQL_BIG_RESULT] [SQL_BUFFER_RESULT] [SQL_CACHE | SQL_NO_CACHE] [SQL_CALC_FOUND_ROWS] select_expr [, select_expr ...] [FROM table_references [PARTITION partition_list] [WHERE where_condition] [GROUP BY {col_name | expr | position} [ASC | DESC], ... [WITH ROLLUP]] [HAVING where_condition] [ORDER BY {col_name | expr | position} [ASC | DESC], ...] [LIMIT {[offset,] row_count | row_count OFFSET offset}] [PROCEDURE procedure_name(argument_list)] [INTO OUTFILE 'file_name' [CHARACTER SET charset_name] export_options | INTO DUMPFILE 'file_name' | INTO var_name [, var_name]] [FOR UPDATE | LOCK IN SHARE MODE]]
WHERE, GROUP BY, HAVING, LIMIT, SELECT,INTO和子句都FOR UPDATE不能LOCK IN SHARE MODE增加子句定义的行数FROM。所以如果table_references等于foo查询不能包含比表更多的行foo。 所以 MySQL 没有这种“优雅”的方式来反透视表。
WHERE
GROUP BY
HAVING
LIMIT
INTO
FOR UPDATE
LOCK IN SHARE MODE
FROM
table_references
foo
一种不使用 UNION 就可以进行这种反透视的方法可以使用连接来完成。我们要为foo表的每一行创建 3 行,因此我们创建一个包含三行的辅助表并将其(交叉)连接到foo表中。现在我们的查询中有三行,用于基表中的每一行foo。每个查询行都可以由适当的数据填充。相反,ELT 函数可以使用 IF 或 CASE。
SQLfiddle
MySQL 5.6 架构设置:
create table foo ( his_name varchar(10), her_name varchar(10), other_name varchar(10)); insert into foo(his_name,her_name,other_name) values ('one','two','three'); insert into foo(his_name,her_name,other_name) values ('four','five','six'); create table aux(line int); insert into aux(line) values(1); insert into aux(line) values(2); insert into aux(line) values(3);
枢轴查询:
select elt(aux.line,foo.his_name,foo.her_name,foo.other_name) all_name from foo cross join aux
结果:
| all_name | |----------| | one | | four | | two | | five | | three | | six |
当然,有不同的方法可以创建一个包含三行值 1、2、3 的表:
使用辅助表:
create table aux(line int); insert into aux(line) values(1); insert into aux(line) values(2); insert into aux(line) values(3);
select line from aux
使用常量表达式:
select 1 line union all select 2 union all select 3
计算行号:我在这里找到了
SELECT @rownum := @rownum + 1 line FROM (SELECT @rownum := 0) r, INFORMATION_SCHEMA.COLUMNS t where @rownum<3
使用字典视图之一:
SELECT ordinal_position line from INFORMATION_SCHEMA.COLUMNS t where table_catalog='def' and table_schema='information_schema' and table_name='COLUMNS' and ordinal_position between 1 and 3
| ORDINAL_POSITION | |------------------| | 1 | | 2 | | 3 |