简体   繁体   English

在MySQL中使用内部连接将列转换为行

[英]Convert columns into rows with inner join in mysql

Please take a look at this fiddle . 请看一下这个小提琴

I'm working on a search filter select box and I want to insert the field names of a table as rows. 我正在研究搜索过滤器选择框,我想将表的字段名称插入为行。

Here's the table schemea: 这是表方案:

CREATE TABLE general
    (`ID` int, `letter` varchar(21), `double-letters` varchar(21))
;

INSERT INTO general
    (`ID`,`letter`,`double-letters`)
VALUES
    (1, 'A','BB'),
    (2, 'A','CC'),
    (3, 'C','BB'),
    (4, 'D','DD'),
    (5, 'D','EE'),
    (6, 'F','TT'),
    (7, 'G','UU'),
    (8, 'G','ZZ'),
    (9, 'I','UU')
;


CREATE TABLE options
    (`ID` int, `options` varchar(15))
;

INSERT INTO options
    (`ID`,`options`)
VALUES
    (1, 'letter'), 
    (2, 'double-letters')
;

The ID field in options table acts as a foreign key, and I want to get an output like the following and insert into a new table: options表中的ID字段用作外键,我想获得如下所示的输出并插入到新表中:

 id   field   value
 1     1       A
 2     1       C
 3     1       D
 4     1       F
 5     1       G
 6     1       I
 7     2       BB
 8     2       CC
 9     2       DD
 10    2       EE
 11    2       TT
 12    2       UU
 13    2       ZZ

My failed attempt: 我失败的尝试:

select DISTINCT(a.letter),'letter' AS field
from general a
INNER JOIN
options b ON b.options = field
union all
select DISTINCT(a.double-letters), 'double-letters' AS field
from general a
INNER JOIN
options b ON b.options = field

Pretty sure you want this: 可以肯定,您想要这样:

select distinct a.letter, 'letter' AS field
  from general a
 cross JOIN options b
 where b.options = 'letter'
union all
select distinct a.`double-letters`, 'double-letters' AS field
  from general a
 cross JOIN options b
 where b.options = 'double-letters'

Fiddle: http://sqlfiddle.com/#!2/bbf0b/18/0 小提琴: http ://sqlfiddle.com/#!2/bbf0b/18/0

A couple to things to point out, you can't join on a column alias. 需要指出的几点,您不能加入列别名。 Because that column you're aliasing is a literal that you're selecting you can specify that literal as criteria in the WHERE clause. 因为要别名的那一列是您要选择的文字,所以可以在WHERE子句中将该文字指定为条件。

You're not really joining on anything between GENERAL and OPTIONS, so what you really want is a CROSS JOIN; 您并不是真正在GENERAL和OPTIONS之间加入任何东西,所以您真正想要的是CROSS JOIN; the criteria that you're putting into the ON clause actually belongs in the WHERE clause. 您放入ON子句中的条件实际上属于WHERE子句。

I just made this query on Oracle. 我只是在Oracle上进行了此查询。 It works and produces the output you described : 它可以工作并产生您描述的输出:

SELECT ID, CASE WHEN LENGTH(VALUE)=2THEN 2 ELSE 1 END AS FIELD, VALUE  
FROM (
SELECT rownum AS ID, letter AS VALUE FROM (SELECT DISTINCT letter FROM general ORDER BY letter)
UNION
SELECT (SELECT COUNT(DISTINCT LETTER) FROM general) +rownum AS ID, double_letters AS VALUE
 FROM (
    SELECT DISTINCT  double_letters FROM general ORDER BY double_letters)
)

It should also run on Mysql. 它也应该在Mysql上运行。

I did not used the options table. 我没有使用options表。 I do not understand his role. 我不明白他的角色。 And for this example, and this type of output it seems unnecessary 对于此示例,这种类型的输出似乎没有必要

Hope this could help you to. 希望这可以帮助您。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM