我有一个用于邮件列表的MySQL数据库,我需要提取数据,因此一个成员记录由一行表示。邮件列表将用户属性存储为EAV。我可以使用以下SQL查询提取所需的所有详细信息,但每个成员记录占用多行:
SELECT a.id, a.name, a.email, b.id, b.name, b.email, c.title, d.val
FROM lists a, listmembers b, fields c, fieldsdata d
WHERE a.id = b.nl
AND b.id = d.eid
AND c.id = d.fid
ORDER BY b.id, a.id, b.name
返回如下内容:
'6', 'Mailing List name', 'owner@mailinglist.com', '10478', 'username', 'mailinglistmember@emailaddress.com', 'Firstname', 'John'
'6', 'Mailing List name', 'owner@mailinglist.com', '10478', 'username', 'mailinglistmember@emailaddress.com', 'Lastname', 'Smith'
'6', 'Mailing List name', 'owner@mailinglist.com', '10478', 'username', 'mailinglistmember@emailaddress.com', 'Country', 'UK'
'6', 'Mailing List name', 'owner@mailinglist.com', '10478', 'username', 'mailinglistmember@emailaddress.com', 'Town', 'Cambridge'
'6', 'Mailing List name', 'owner@mailinglist.com', '10478', 'username', 'mailinglistmember@emailaddress.com', 'Shoesize', '7'
'6', 'Mailing List name', 'owner@mailinglist.com', '10478', 'username', 'mailinglistmember@emailaddress.com', 'Favourite Colour', 'Purple'
我需要使用SQL将其展平为一行,只需要与键名字,姓氏,城镇和国家/地区相关的值
数据库不是很大,fieldsdata表是最大的,有大约5500行。
看起来像是一个真正的痛苦,所以任何指针都会感激不尽。 !
答案 0 :(得分:2)
如果我正确理解您的问题,您可以MAX
与CASE
一起展示您的搜索结果:
SELECT l.id, l.name, l.email, lm.id, lm.name, lm.email,
MAX(CASE WHEN f.title = 'Firstname' THEN fd.val END) FirstName,
MAX(CASE WHEN f.title = 'Lastname' THEN fd.val END) Lastname,
MAX(CASE WHEN f.title = 'Country' THEN fd.val END) Country,
MAX(CASE WHEN f.title = 'Town' THEN fd.val END) Town
FROM lists l
JOIN listmembers lm ON l.id=lm.nl
JOIN fieldsdata fd ON fd.eid = lm.id
JOIN fields f ON f.id = fd.fid
GROUP BY l.id, lm.id
这假设您的列表中的id字段是您的唯一标识符。如果没有,您需要向GROUP BY添加其他字段(很可能是listmembers表中的id字段)。
答案 1 :(得分:2)
对于发现此问题的任何人(像我一样),您的查询与SQL Server而不是MySQL相关,可以选择Pivot查询。
SELECT id, name, email, id2, name2, email2, [Firstname], [Lastname],
[Country], [Town]
FROM (select id, name, email, id2, name2, email2, title, val from yourresults) ps
PIVOT (
MAX(val)
FOR title IN ([Firstname], [Lastname], [Country], [Town])
) as pvt
请参阅SQL fiddle(使用上面的sgeddes SQL小提琴 - 谢谢)
或在MS Access中:
TRANSFORM Max(val)
SELECT id, name, email, id2, name2, email2
FROM yourresults
GROUP BY id, name, .email, id2, name2, email2
PIVOT title In ("FirstName","LastName","Country","Town");
答案 2 :(得分:-2)
EAV表是一种糟糕的设计选择,只有在您事先无法知道需要哪些字段时才应使用。诸如firstname之类的字段可以预先知道您将需要它们并且应该在适当的相关表中。如果您想使用EAV,至少停止使用关系数据库并使用为此设计的NOSQL数据库。
要获得您想要的结果,您需要为每种类型的数据加入EAV表一次。