[英]SQL Query with multiple tables and joins
我有多个表格-用户/事件/预订/位置-我需要从中收集数据。
我没有SQL技能,只是想将某些东西缝合在一起。 到目前为止,我可以通过以下查询获取所有用户数据和预订数据:
SELECT ds_usermeta.first_name, ds_usermeta.last_name,
ds_usermeta.phone_number, ds_usermeta.mobile_number, ds_usermeta.user_emerg_name,
ds_usermeta.user_emerg_rel, ds_usermeta.user_emerg_phone,
ds_em_bookings.booking_date, ds_em_bookings.booking_comment
FROM
(
SELECT user_id,
MAX(CASE WHEN meta_key = 'first_name' THEN meta_value END) first_name,
MAX(CASE WHEN meta_key = 'last_name' THEN meta_value END) last_name,
MAX(CASE WHEN meta_key = 'phone_number' THEN meta_value END) phone_number,
MAX(CASE WHEN meta_key = 'mobile_number' THEN meta_value END) mobile_number,
MAX(CASE WHEN meta_key = 'user_emerg_name' THEN meta_value END) user_emerg_name,
MAX(CASE WHEN meta_key = 'user_emerg_rel' THEN meta_value END) user_emerg_rel,
MAX(CASE WHEN meta_key = 'user_emerg_phone' THEN meta_value END) user_emerg_phone
FROM ds_usermeta
WHERE EXISTS
(
SELECT *
FROM ds_em_bookings
WHERE ds_em_bookings.person_id = ds_usermeta.user_id
)
GROUP BY ds_usermeta.user_id
) ds_usermeta JOIN ds_em_bookings
ON ds_usermeta.user_id = ds_em_bookings.person_id
ORDER BY ds_em_bookings.event_id
由于用户数据存储在行中,因此不能简单地选择-用户元数据表示例:
umeta_id user_id meta_key meta_value
-----------------------------------------------
1 1 nickname mikesmith
2 1 first_name Mike
3 1 last_name Smith
我的问题是ds_em_bookings中的预订数据只是ID。 要获得一个“好名字”,我需要通过匹配ID从ds_em_events中将其提取。 我还需要通过匹配ds_em_events中的ID从ds_em_locations中提取位置名称。
那我希望有这样的东西
First_name | Last_name | booking_date | event_name | location_name
仅使用上面的所有用户字段。 我已经基于此尝试了多种组合:
(
SELECT event_name
FROM ds_em_events
WHERE ds_em_events.event_id = ds_em_bookings.event_id
JOIN ds_em_bookings
ON ds_em_events.event_id = ds_em_bookings.event_id
)
(
SELECT location_name
FROM ds_em_locations
WHERE ds_em_locations.location_id = ds_em_events.location_id
LEFT JOIN ds_em_events
ON ds_em_locations.location_id = ds_em_events.location_id
)
但是无法确定如何/在何处放置此内容或类似内容,以便从ds_em_events中提取event_name以及找到的每个预订的位置(其ID在ds_em_events表中)。
抱歉,这是一篇很长的文章,但我希望有足够的细节才能弄清楚。 欢迎任何帮助-请记住我是新手-仅从SQL开始。
您可以联接多个表,因此只需将所有联接链接到主查询,然后从这些表中选择列:
SELECT ds_usermeta.first_name,
ds_usermeta.last_name,
...
ds_em_bookings.booking_date,
ds_em_bookings.booking_comment,
ds_em_events.event_name,
ds_em_locations.location_name
FROM
(SELECT user_id,
MAX(CASE WHEN meta_key = 'first_name' THEN meta_value END) first_name,
MAX(CASE WHEN meta_key = 'last_name' THEN meta_value END) last_name,
...
FROM ds_usermeta
GROUP BY ds_usermeta.user_id
) ds_usermeta
INNER JOIN ds_em_bookings ON ds_usermeta.user_id = ds_em_bookings.person_id
INNER JOIN ds_em_events ON ds_em_events.event_id = ds_em_bookings.event_id
INNER JOIN ds_em_locations ON ds_em_locations.location_id = ds_em_events.location_id
ORDER BY ds_em_bookings.event_id
请注意,当您拥有JOIN
您也不需要在WHERE
子句中比较ID。 使用INNER JOIN
而不是WHERE EXISTS
因为那样会消除所有其他表中没有对应行的行。
还要注意, LEFT JOIN
将列出左表中的所有行-如果右表中没有相应的行,则将显示NULL。 注意示例中的细微差别。 您已经完成:
SELECT location_name
FROM ds_em_locations
LEFT JOIN ds_em_events ON ds_em_locations.location_id = ds_em_events.location_id
它会将事件连接到位置,并为您提供所有位置,甚至是没有事件的位置-但是您的主要查询却采用其他方式,因此我们
JOIN ds_em_locations ON ds_em_locations.location_id = ds_em_events.location_id
会将地点加入活动/预订,因此没有预订就不会显示地点。 如果要显示所有此类行,则可能需要执行RIGHT JOIN
或类似操作。
有关JOIN的Wiki文章非常详尽-请阅读!
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.