我有一张这样的表:
+------------------------+-------+------+-------+------+
| user | TELPE | CRS2 | MECAN | GOPI |
+------------------------+-------+------+-------+------+
| user1.foo@my-email.com | NULL | NULL | 1 | NULL |
+------------------------+-------+------+-------+------+
| user2.foo@my-email.com | 1 | NULL | 1 | NULL |
+------------------------+-------+------+-------+------+
我很难找到返回值为1的特定用户的列名称的请求。
选择手动列不是一个选项,好像今天只有4列, 下周可能会有300人。
例如,搜索user1会得到以下结果:
+-------------+
| Books |
+-------------+
| MECAN |
+-------------+
和user2:
+-------------+
| Books |
+-------------+
| TELPE |
+-------------+
| MECAN |
+-------------+
我的Mysql技能不是很高,所以感谢任何帮助,
非常感谢提前。
答案 0 :(得分:1)
您需要将列转换为行,此过程称为unpivot。
你可以用UNIONS做到这一点。
<强>查询强>
SELECT
USER
, TELPE AS 'column_value'
, 'TELPE' AS 'column_source'
FROM
users
WHERE
TELPE = 1
UNION ALL
SELECT
USER
, CRS2 AS 'column_value'
, 'CRS2' AS 'column_source'
FROM
users
WHERE
CRS2 = 1
UNION ALL
SELECT
USER
, MECAN AS 'column_value'
, 'MECAN' AS 'column_source'
FROM
users
WHERE
MECAN = 1
UNION ALL
SELECT
USER
, GOPI AS 'column_value'
, 'GOPI' AS 'column_source'
FROM
users
WHERE
GOPI = 1
<强>结果强>
user column_value column_source
---------------------- ------------ ---------------
user2.foo@my-email.com 1 TELPE
user1.foo@my-email.com 1 MECAN
user2.foo@my-email.com 1 MECAN
现在,我们可以将此查询用作已交付的表格,以过滤所需的结果。
<强>查询强>
SELECT
DISTINCT
column_source
FROM (
SELECT
USER
, TELPE AS 'column_value'
, 'TELPE' AS 'column_source'
FROM
users
WHERE
TELPE = 1
UNION ALL
SELECT
USER
, CRS2 AS 'column_value'
, 'CRS2' AS 'column_source'
FROM
users
WHERE
CRS2 = 1
UNION ALL
SELECT
USER
, MECAN AS 'column_value'
, 'MECAN' AS 'column_source'
FROM
users
WHERE
MECAN = 1
UNION ALL
SELECT
USER
, GOPI AS 'column_value'
, 'GOPI' AS 'column_source'
FROM
users
WHERE
GOPI = 1
)
AS
users
WHERE
users.user = 'user1.foo@my-email.com'
AND
users.column_value = 1
<强>结果强>
| column_source |
|---------------|
| MECAN |
demo http://www.sqlfiddle.com/#!9/3ed091/19
<强> EDITED 强>
手动选择列不是一个选项,好像今天只有4列,下周可能会有300列。
然后您需要转向动态SQL生成。
首先,当需要数字生成器时,此查询将生成从2到1001的1000个数字。 为什么我们需要一个数字生成器将在以后变得更加清晰。
<强>查询强>
SELECT
@row := @row + 1 AS number
FROM (
SELECT 0 UNION ALL SELECT 1 UNION ALL SELECT 2 UNION ALL SELECT 3 UNION ALL SELECT 4 UNION ALL SELECT 5 UNION ALL SELECT 6 UNION ALL SELECT 7 UNION ALL SELECT 8 UNION ALL SELECT 9
)
AS row1
CROSS JOIN (
SELECT 0 UNION ALL SELECT 1 UNION ALL SELECT 2 UNION ALL SELECT 3 UNION ALL SELECT 4 UNION ALL SELECT 5 UNION ALL SELECT 6 UNION ALL SELECT 7 UNION ALL SELECT 8 UNION ALL SELECT 9
)
AS row2
CROSS JOIN (
SELECT 0 UNION ALL SELECT 1 UNION ALL SELECT 2 UNION ALL SELECT 3 UNION ALL SELECT 4 UNION ALL SELECT 5 UNION ALL SELECT 6 UNION ALL SELECT 7 UNION ALL SELECT 8 UNION ALL SELECT 9
)
AS row3
CROSS JOIN (
SELECT @row := 1
)
AS init_user_param
<强>结果强>
2
3
4
5
6
7
8
9
10
....
....
990
991
992
993
994
995
996
997
998
999
1000
1001
现在我们需要一种方法来获取表用户的所有列。
<强>查询强>
SELECT
GROUP_CONCAT(COLUMN_NAME) AS COLUMN_NAME
FROM
information_schema.COLUMNS
WHERE
TABLE_NAME = 'users'
AND
TABLE_SCHEMA <> 'performance_schema'
<强>结果强>
COLUMN_NAME
----------------------------
user,TELPE,CRS2,MECAN,GOPI
现在我们要生成一个像
这样的唯一列表user TELPE
user CRS2
...
...
user GOPI
现在我们将数字生成器与查询结合起来以获取列。 我们还使用SUBSTRING_INDEX来溢出逗号分隔值。
<强>查询强>
SELECT
DISTINCT
SUBSTRING_INDEX(SUBSTRING_INDEX(COLUMN_NAME, ',', 1), ',', -1) column1
, SUBSTRING_INDEX(SUBSTRING_INDEX(COLUMN_NAME, ',', generator.number), ',', -1) column2
FROM (
SELECT
GROUP_CONCAT(COLUMN_NAME) AS COLUMN_NAME
FROM
information_schema.COLUMNS
WHERE
TABLE_NAME = 'users'
AND
TABLE_SCHEMA <> 'performance_schema'
)
AS user_column
CROSS JOIN (
SELECT
@row := @row + 1 AS number
FROM (
SELECT 0 UNION ALL SELECT 1 UNION ALL SELECT 2 UNION ALL SELECT 3 UNION ALL SELECT 4 UNION ALL SELECT 5 UNION ALL SELECT 6 UNION ALL SELECT 7 UNION ALL SELECT 8 UNION ALL SELECT 9
)
AS row1
CROSS JOIN (
SELECT 0 UNION ALL SELECT 1 UNION ALL SELECT 2 UNION ALL SELECT 3 UNION ALL SELECT 4 UNION ALL SELECT 5 UNION ALL SELECT 6 UNION ALL SELECT 7 UNION ALL SELECT 8 UNION ALL SELECT 9
)
AS row2
CROSS JOIN (
SELECT 0 UNION ALL SELECT 1 UNION ALL SELECT 2 UNION ALL SELECT 3 UNION ALL SELECT 4 UNION ALL SELECT 5 UNION ALL SELECT 6 UNION ALL SELECT 7 UNION ALL SELECT 8 UNION ALL SELECT 9
)
AS row3
CROSS JOIN (
SELECT @row := 1
)
AS init_user_param
)
AS generator
<强>结果强>
column1 column2
------- ---------
user TELPE
user CRS2
user MECAN
user GOPI
使SQL生成完全动态
<强>查询强>
SET @sql_union = NULL;
SELECT
GROUP_CONCAT(
CONCAT(
"
SELECT
",column1,"
, ",column2," AS 'column_value'
, '",column2,"' AS 'column_source'
FROM
users
WHERE
",column2," = 1
"
)
SEPARATOR 'UNION ALL'
)
FROM (
SELECT
DISTINCT
SUBSTRING_INDEX(SUBSTRING_INDEX(COLUMN_NAME, ',', 1), ',', -1) column1
, SUBSTRING_INDEX(SUBSTRING_INDEX(COLUMN_NAME, ',', generator.number), ',', -1) column2
FROM (
SELECT
GROUP_CONCAT(COLUMN_NAME) AS COLUMN_NAME
FROM
information_schema.COLUMNS
WHERE
TABLE_NAME = 'users'
AND
TABLE_SCHEMA <> 'performance_schema'
)
AS user_columns
CROSS JOIN (
SELECT
@row := @row + 1 AS number
FROM (
SELECT 0 UNION ALL SELECT 1 UNION ALL SELECT 2 UNION ALL SELECT 3 UNION ALL SELECT 4 UNION ALL SELECT 5 UNION ALL SELECT 6 UNION ALL SELECT 7 UNION ALL SELECT 8 UNION ALL SELECT 9
)
AS row1
CROSS JOIN (
SELECT 0 UNION ALL SELECT 1 UNION ALL SELECT 2 UNION ALL SELECT 3 UNION ALL SELECT 4 UNION ALL SELECT 5 UNION ALL SELECT 6 UNION ALL SELECT 7 UNION ALL SELECT 8 UNION ALL SELECT 9
)
AS row2
CROSS JOIN (
SELECT 0 UNION ALL SELECT 1 UNION ALL SELECT 2 UNION ALL SELECT 3 UNION ALL SELECT 4 UNION ALL SELECT 5 UNION ALL SELECT 6 UNION ALL SELECT 7 UNION ALL SELECT 8 UNION ALL SELECT 9
)
AS row3
CROSS JOIN (
SELECT @row := 1
)
AS init_user_param
)
AS generator
)
AS generator_union_sql INTO @sql_union;
SET @sql = CONCAT(
"
SELECT
DISTINCT
column_source
FROM (
"
,@sql_union,
"
)
AS
users
WHERE
users.user = 'user1.foo@my-email.com'
AND
users.column_value = 1
"
);
PREPARE queryUser FROM @sql;
EXECUTE queryUser;
<强>结果强>
column_source
---------------
MECAN
答案 1 :(得分:0)
我怀疑你正在寻找像
这样的东西SELECT user, if(telpe=1,"TELPE","") as rTELPE, if(CRS2=1,"CRS2","") as rCRS2 from myTable
答案 2 :(得分:0)
我对你的问题的理解是:
SELECT 'TELPE' FROM yourTable WHERE telpe = 1 AND user = 'user1.foo@my-email.com'
UNION ALL
SELECT 'CRS2 ' FROM yourTable WHERE crs2 = 1 AND user = 'user1.foo@my-email.com'
UNION ALL
SELECT 'MECAN' FROM yourTable WHERE mecam = 1 AND user = 'user1.foo@my-email.com'
UNION ALL
SELECT 'GOPI' FROM yourTable WHERE gopi = 1 AND user = 'user1.foo@my-email.com'