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

时间:2016-01-28 16:28:58

标签: mysql sql wordpress

我有多个表 - 用户/事件/预订/位置 - 我需要从中收集数据。

我没有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开始。

1 个答案:

答案 0 :(得分:1)

您可以加入多个表,只需将所有联接链接到主查询,然后从这些表中选择列:




  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(当meta_key ='first_name'THEN meta_value END时)例如first_name,
 MAX(当meta_key ='last_name'THEN meta_value END时)例句last_name,
 ...& #xA; 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文章非常详尽 - 阅读它!