我正在尝试创建一个查询,将规范化表格中的内容格式化为单行。
我想要的是这样的,每个联系人都有一行:
Name Mobile Office Home
--------------- ----------- ---------- ----------
Fred Flintstone 123-456-7890 234-567-8901 789-012-3456
Barney Rubble 456-789-0123 678-901-2345
Wilma Flintstone 567-890-1234 789-012-3456
我从最新查询得到的是这样,每个联系人有多行:
Name Phone Phone_Type
--------------- ------------ -----------
Fred Flintstone 123-456-7890 Mobile
Fred Flintstone 234-567-8901 Office
Fred Flintstone 789-012-3456 Home
Barney Rubble 456-789-0123 Mobile
Barney Rubble 678-901-2345 Home
Wilma Flintstone 567-890-1234 Mobile
Wilma Flintstone 789-012-3456 Home
以下是涉及的表格(简化):
contacts
----------
contact_id
name
link_contact_phonenumbers
-------------------------
contact_id
phone_number_id
phone_numbers
-------------
phone_number_id
phone_number
type_id
ref_phone_types
---------------
type_id
name
这是我到目前为止所做的:
SELECT
cn.name as Name,
concat( left(ph.phone_number,3) , "-" , mid(ph.phone_number,4,3) , "-", right(ph.phone_number,4)) as Phone,
pt.name as Phone_Type
FROM
contacts cn
LEFT JOIN link_contact_phonenumbers lp ON lp.contact_id = cn.contact_id
LEFT JOIN phone_numbers ph ON ph.phone_number_id = lp.phone_number_id
LEFT JOIN ref_phone_types pt ON pt.type_id = ph.type_id
我查看了使用GROUP_CONCAT()函数,但是它将所有内容都拉到了一个列中。我需要他们进入他们自己的专栏。
我一直在研究与IF()结合的子查询,但还没有想出来。
有没有办法在纯SQL中执行此操作?
答案 0 :(得分:0)
听起来你可以用几个连接来完成你想要的东西:
Select a.name, c.phone_number, d.phone_number, e.phone_number from contacts a
left join link_contact_phonenumbers b on a.contact_id = b.contact_id
left join phone_numbers c on b.phone_number_id = c.phone_number_id and c.type_id = "whatever id is mobile"
left join phone_numbers d on b.phone_number_id = d.phone_number_id and d.type_id = "whatever id is office"
left join phone_numbers e on b.phone_number_id = e.phone_number_id and e.type_id = "whatever id is home"
我不知道这是否是最有效的方法,我现在也没有数据库可以测试它可能会关闭,但它应该指向正确的方向。如果第一个连接添加多行,也可能需要按a.name分组。
答案 1 :(得分:0)
以下是将来会发现这一点的其他解决方案:
SELECT
cn.name as Name,
MAX(CASE WHEN pt.type_id = '1' THEN ph.phone_number ELSE NULL END) as Mobile,
MAX(CASE WHEN pt.type_id = '2' THEN ph.phone_number ELSE NULL END) as Office,
MAX(CASE WHEN pt.type_id = '3' THEN ph.phone_number ELSE NULL END) as Home
FROM
contacts cn
LEFT JOIN link_contact_phonenumbers lp ON lp.contact_id = cn.contact_id
LEFT JOIN phone_numbers ph ON ph.phone_number_id = lp.phone_number_id
LEFT JOIN ref_phone_types pt ON pt.type_id = ph.type_id
GROUP BY cn.contact_id
在此处找到此解决方案:How to Denormalize a Normalized Table Using SQL
我不确定这是否效率最高,但确实有效。