繁体   English   中英

具有多个表和联接的SQL查询

[英]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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM