MySQL - 将行显示为列(尽可能简单)
Posted
技术标签:
【中文标题】MySQL - 将行显示为列(尽可能简单)【英文标题】:MySQL - Display rows as columns (as simple as possible) 【发布时间】:2016-02-28 16:40:19 【问题描述】:几周以来,我一直在处理以下问题。我已经阅读了我找到的所有教程和 sn-ps,但无法完成这项工作。
我有下表(wordpress 数据库):
post_id meta_key meta_value
802 _billing_first_name John
802 _billing_last_name Johnson
802 _billing_first_name2 Jack
802 _billing_last_name2 Jackson
802 _billing_first_name3 Jason
802 _billing_last_name3 Jasonson
803 _billing_first_name Jamie
803 _billing_last_name Jameson
803 _billing_first_name2 Oliver
803 _billing_last_name2 Olverson
我需要一份所有订单中所有人的名单。该列表应如下所示。
ID Firstname Lastname
802 John Johnson
802 Jack Jackson
802 Jason Jasonson
803 Jamie Jameson
803 Oliver Oliverson
每个订单可能有无限的名称。一个订单可能是 20 人,而下一个订单可能是一个人。
【问题讨论】:
【参考方案1】:您可以使用自加入:
SELECT t1.post_id AS ID, t1.meta_value AS Firstname, t2.meta_value AS Lastname
FROM tab t1
JOIN tab t2
ON t1.post_id = t2.post_id
AND t1.meta_key LIKE '_billing_first_name%'
AND t2.meta_key LIKE '_billing_last_name%'
AND RIGHT(t1.meta_key, 3) = RIGHT(t2.meta_key,3); -- up to 999 users
LiveDemo
输出:
╔═════╦═══════════╦══════════╗
║ ID ║ FirstName ║ LastName ║
╠═════╬═══════════╬══════════╣
║ 802 ║ John ║ Johnson ║
║ 802 ║ Jack ║ Jackson ║
║ 802 ║ Jason ║ Jasonson ║
║ 803 ║ Jamie ║ Jameson ║
║ 803 ║ Oliver ║ Olverson ║
╚═════╩═══════════╩══════════╝
重点是mysql
是关系型数据库,不适用于EAV
设计。这个解决方案在非常大的表中可能会很慢,因为连接条件是non-SARGable
。
编辑:
我猜你想加入:
_billing_first_name2
与 _billing_email002
您可以使用普通数字处理000
,但性能会很差:
SELECT t1.post_id AS ID, t1.meta_value AS Firstname, t2.meta_value AS Email
FROM tab t1
JOIN tab t2
ON t1.post_id = t2.post_id
AND t1.meta_key LIKE '_billing_first_name%'
AND t2.meta_key LIKE '_billing_last_email%' --email
AND CONCAT(
IF(SUBSTRING(t1.meta_key,-3,1) REGEXP '[0-9]',SUBSTRING(t1.meta_key,-3,1), '0'),
IF(SUBSTRING(t1.meta_key,-2,1) REGEXP '[0-9]',SUBSTRING(t1.meta_key,-2,1), '0'),
IF(SUBSTRING(t1.meta_key,-1,1) REGEXP '[0-9]',SUBSTRING(t1.meta_key,-1,1), '0')
) =
CONCAT(
IF(SUBSTRING(t2.meta_key,-3,1) REGEXP '[0-9]',SUBSTRING(t2.meta_key,-3,1), '0'),
IF(SUBSTRING(t2.meta_key,-2,1) REGEXP '[0-9]',SUBSTRING(t2.meta_key,-2,1), '0'),
IF(SUBSTRING(t2.meta_key,-1,1) REGEXP '[0-9]',SUBSTRING(t2.meta_key,-1,1), '0')
)
【讨论】:
我喜欢你的解决方案,你能解释一下你是如何正确链接名字和姓氏的吗?即杰克和杰克逊而不是奥尔弗森。由于您不能使用 ID 作为参考(并且希望表格正确排序。我仍在尝试在我自己的查询中弄清楚这一点 @davejal 每个带有 EAV 设计的键都有编号,最后AND RIGHT(t1.meta_key, 3) = RIGHT(t2.meta_key,3);
完成这项工作。只是 "ne2" = "ne2", "ne3" = "ne3" ...
感谢您的跟进。不过,我将不得不查找 eav 设计
谢谢 lad2025。漂亮而简单的代码。当我们获得超过 999 个用户时会发生什么。 IE。 5 个用户的 200 个订单。
@Virik 它将工作到_billing_first_name999
。如果需要更多信息,您需要使用AND RIGHT(t1.meta_key, 4) = RIGHT(t2.meta_key,4);
。总记录数不受此限制,因此您可以拥有 100 个用户,每个用户有 999 个订单以上是关于MySQL - 将行显示为列(尽可能简单)的主要内容,如果未能解决你的问题,请参考以下文章