SQL查询将列拆分为多行

时间:2017-10-25 14:44:32

标签: sql wordpress split pivot-table

这很可能是以某种方式复制的。我查看并尝试了许多找到的答案。我这几天都在苦苦挣扎,我只是无法让它发挥作用,或者弄清楚如何应用我发现的一些例子。

似乎最想将所有列转换为行,这不是我想要的。据我所知,我可能需要的是univot和/或UNION?

我从Wordpresstable“wp_usermeta”获取数据。

Wordpress表结构如下所示:

user_id | meta_key   | meta_value
1       | FirstnameA | Klaus
1       | SecondnameA| Reed
1       | FirstnameB | Herbert
1       | SecondnameB| Hall
2       | FirstnameA | Max
2       | SecondnameA| Musterman
....

我需要什么:

ID | Firstname_A | Lastname_A | Adress_A 

ID | Firstname_B | Lastname_B | Adress_B

两行都属于同一个ID。

我当前的查询内容如下:

SELECT user_id,

MAX(CASE WHEN meta_key='firstnameA' THEN meta_value ELSE null END)  FirstnameA,
MAX(CASE WHEN meta_key='lastnameA' THEN meta_value ELSE null END) Lastname_A,
MAX(CASE WHEN meta_key='adressA' THEN meta_value ELSE null END) Adress_A,
MAX(CASE WHEN meta_key='firstnameB' THEN meta_value ELSE null END) FirstnameB,
MAX(CASE WHEN meta_key='lastnameB' THEN meta_value ELSE null END) Lastname_B,
MAX(CASE WHEN meta_key='adressB' THEN meta_value ELSE null END) Adress_B

FROM wp_usermeta
GROUP BY user_id

我的结果是:

ID | Firstname_A | Lastname_A | Adress_A | Firstname_B | Lastname_B | Adress_B

MySQL-Version:5.7

我的approch与JOIN for @janh也显示实际的meta_key:

SET SQL_BIG_SELECTS=1;
select m1.user_id, m1.meta_value as Vorname_M, m2.meta_value as Nachname_M,m3.meta_value as Adresse_M,m4.meta_value as Telefon_M,m5.meta_value as Mail_M,
                   m6.meta_value as Vorname_V, m7.meta_value as Nachname_V,m8.meta_value as Adresse_V,m9.meta_value as Telefon_V,m10.meta_value as Mail_V,
                   m11.meta_value as Kinder, m12.meta_value as Kindergeburtstage,
                   m13.meta_value as Vorname_L, m14.meta_value as Nachname_L,m15.meta_value as Adresse_L,m16.meta_value as Telefon_L,m17.meta_value as Mail_L,
                   m18.meta_value as Arbeitskreise
from wp_usermeta m1
join wp_usermeta m2 on (m1.user_id = m2.user_id and m2.meta_key = 'nachnamemother')
join wp_usermeta m3 on (m2.user_id = m3.user_id and m3.meta_key = 'adress_mother')
join wp_usermeta m4 on (m3.user_id = m4.user_id and m4.meta_key = 'phone_mother')
join wp_usermeta m5 on (m4.user_id = m5.user_id and m5.meta_key = 'mail_mother')
join wp_usermeta m6 on (m5.user_id = m6.user_id and m6.meta_key = 'first_name_father')
join wp_usermeta m7 on (m6.user_id = m7.user_id and m7.meta_key = 'first_name_father_8')
join wp_usermeta m8 on (m7.user_id = m8.user_id and m8.meta_key = 'adress_father')
join wp_usermeta m9 on (m8.user_id = m9.user_id and m9.meta_key = 'phone_mother_16')
join wp_usermeta m10 on (m9.user_id = m10.user_id and m10.meta_key = 'mail_father')

join wp_usermeta m11 on (m10.user_id = m11.user_id and m11.meta_key = 'childs')
join wp_usermeta m12 on (m11.user_id = m12.user_id and m12.meta_key = 'birth_data')

join wp_usermeta m13 on (m12.user_id = m12.user_id and m13.meta_key = 'leben_vorname')
join wp_usermeta m14 on (m13.user_id = m13.user_id and m14.meta_key = 'leben_nachname')
join wp_usermeta m15 on (m14.user_id = m14.user_id and m15.meta_key = 'leben_adress')
join wp_usermeta m16 on (m15.user_id = m15.user_id and m16.meta_key = 'leben_phone')
join wp_usermeta m17 on (m16.user_id = m16.user_id and m17.meta_key = 'leben_mail')

join wp_usermeta m18 on (m17.user_id = m17.user_id and m18.meta_key = 'ak')

where m1.meta_key = 'firstnamemother'

什么对我有用:

SELECT user_id,

CASE WHEN meta_key LIKE '%mother' THEN 'mother' 
     WHEN meta_key LIKE '%father' THEN 'father' 
     WHEN meta_key LIKE '%8' THEN 'father'
     END AS AorB,


MAX(CASE WHEN meta_key='firstnamemother' 
           OR meta_key='first_name_father' 
         THEN meta_value END) AS Vorname,

MAX(CASE WHEN meta_key='nachnamemother' 
           OR meta_key='first_name_father_8' 
           THEN meta_value END) AS Nachname,

 MAX(CASE WHEN meta_key='adress_mother' 
           OR meta_key='adress_father' 
           THEN meta_value END) AS Adresse

FROM wp_usermeta
GROUP BY
user_id,
CASE WHEN meta_key LIKE '%mother' THEN 'mother' 
     WHEN meta_key LIKE '%father' THEN 'father' 
     WHEN meta_key LIKE '%8' THEN 'father'
     END

3 个答案:

答案 0 :(得分:2)

UNION ALL可以解决问题。

SELECT user_id,
MAX(CASE WHEN meta_key='firstnameA' THEN meta_value ELSE null END)  FirstnameA,
MAX(CASE WHEN meta_key='lastnameA' THEN meta_value ELSE null END) Lastname_A,
MAX(CASE WHEN meta_key='adressA' THEN meta_value ELSE null END) Adress_A
FROM wp_usermeta
GROUP BY user_id
UNION ALL
SELECT user_id,
MAX(CASE WHEN meta_key='firstnameB' THEN meta_value ELSE null END) FirstnameB,
MAX(CASE WHEN meta_key='lastnameB' THEN meta_value ELSE null END) Lastname_B,
MAX(CASE WHEN meta_key='adressB' THEN meta_value ELSE null END) Adress_B
FROM wp_usermeta
GROUP BY user_id

答案 1 :(得分:1)

我想连接应该这样做,不应该吗?

这样的东西
select ID, pm_firstname.meta_value as firstname, pm_lastname.meta_value lastname, pm_address.meta_value as address FROM wp_posts
    INNER JOIN wp_postmeta pm_firstname ON (wp_posts.ID = pm_firstname.post_id AND pm_firstname.meta_key = 'firstname')
    INNER JOIN wp_postmeta pm_lastname ON (wp_posts.ID = pm_lastname.post_id AND pm_lastname.meta_key = 'lastname')
    INNER JOIN wp_postmeta pm_address ON (wp_posts.ID = pm_address.post_id AND pm_address.meta_key = 'address')
;

应该很好地结合你的结果。您需要哪种类型的加入取决于您的数据以及如果某个帖子的字段不存在会发生什么。

答案 2 :(得分:1)

根据您对表的编辑并希望A& B作为行不是单独的列,您可以稍微更改条件聚合并添加新列以跟踪记录是A还是B.然后按它分组,您的聚合应该给您想要的。

SELECT
    ID
    ,CASE WHEN user_key LIKE '%A' THEN 'A' ELSE 'B' END AS AorB
    ,MAX(CASE WHEN meta_key LIKE 'first%' THEN meta_value END) AS FirstName
    ,MAX(CASE WHEN meta_key LIKE 'last%' OR meta_key LIKE 'sec%' THEN meta_value END) AS LastName
    ,MAX(CASE WHEN meta_key LIKE 'add%' THEN meta_value END) AS Address
FROM
    wp_usermeta
GROUP BY
    user_id
    ,CASE WHEN meta_key LIKE '%A' THEN 'A' ELSE 'B' END

因此,您只需要测试firstname而不是firstnameb,因为如果您测试整个字符串,则会消除A结果,lastname和地址也是如此。请注意,在执行case expression时,如果您不包含ELSE,那么与when语句不匹配的内容将自动为NULL,因此您也可以将其排除在外。

根据您的评论,您可以在OR表达式中添加额外的WHENCASE语句,即使标准不应该只是x#的测试用例。另外,使用first%代替firstname%会立即占2个案例,或者您可能会考虑f%。最后,您可以使用last%sec%

如果您有特定数量的firstnameA,B,C,D。您也可以使用RIGHT(meta_key,1)代替案例表达式,只需在group by中使用相同的内容。如果你有时候需要超过1个字符,而其他人则需要更加困难但你可以根据案例表达式进行混合来测试,例如CASE WHEN meta_key LIKE '%AB' THEN RIGHT(meta_key,2) ELSE RIGHT(meta_key,1) END