繁体   English   中英

我在MySQL中有4个表-与没有重复的第4个表联接(可能为null值)

[英]I have 4 tables in MySQL - Join with 4th table without duplicates (possible null value)

好的,我正在处理4个表,我需要查询不返回任何重复项,如果需要,则返回null值。 不幸的是,由于我使用的框架存在限制,因此无法使用UNION。 这是我的桌子:

users Table
------------------------------------------------------
id      name
------------------------------------------------------
1       jane
2       john
3       skip


songs Table
------------------------------------------------------
id      artist      title
------------------------------------------------------
1       devo        whip
2       snake       hiss
3       america     great
4       elvis       blues


song_history Table
------------------------------------------------------
singer_id   song_id
------------------------------------------------------
2       1
2       2
2       3
2       4


song_current Table
------------------------------------------------------
singer_id   song_id     event_id
------------------------------------------------------
2       3       20
2       4       22

我已经编写了两个查询,它们可以满足所需结果的一半,这是第一个查询:

SELECT name, artist, title
FROM users AS user
LEFT JOIN song_history AS history ON user.id = history.singer_id
LEFT JOIN songs AS song ON history.song_id = song.id 
WHERE user.id = 2

上面的查询为我提供了john用户的song_history中所有歌曲的列表:

name    artist      title   
-----------------------------
john  | devo      | whip    |   
john  | snake     | hiss    |   
john  | america   | great   |   

这是所需结果另一半的第二个查询:

SELECT name, artist, title, event_id
FROM users AS user
LEFT JOIN song_history AS history ON user.id = history.singer_id
LEFT JOIN songs AS song ON history.song_id = song.id
LEFT JOIN song_current AS csongs ON csongs.singer_id = user.id
AND csongs.song_id = history.song_id
WHERE user.id = 2
AND event_id = 20

上面的查询为我提供了song_history中所有在song_current表中还为event_id为20的歌曲的列表

name    artist      title   event_id
--------------------------------------------
john  | america   | great   |   20

现在,由于我使用的框架,我受到了限制,这限制了我使用UNION,所以我迷失了没有UNION的方式或方法。

这是我要寻找的结果:

name    artist      title   event_id
-------------------------------------
john  | devo      | whip    |   null
john  | snake     | hiss    |   null
john  | america   | great   |   20
john  | elvis     | blues   |   null

基本上,我需要一个给定用户在song_history表中的所有歌曲的列表,如果event_id匹配,则需要显示event_id;如果不匹配,则需要显示null,但仍显示在song_history表。

song_history表将始终包含song_current中的内容(没有event_id),但是,song_current并不总是包含在song_history中找到的数据。

如果可以使用UNION,我将简单地使用上面两个成功的查询,并且可以解决我的问题,但是,由于我不能使用UNION,所以我对LEFT INNER,LEFT OUTER和其他JOINS的所有尝试都使我望而却步。

任何帮助是极大的赞赏!

编辑:

请注意,song_current表将具有其他event_id,这将使我无法像这样使用WHERE / OR:

AND(event_id = 20 OR event_id为NULL);

Joomla 3.3框架最近才包含UNION语句,目前无法在多个列上使用。

这是一个在phpMyAdmin中可以正常工作的UNION查询的示例:

注意:还有一个名为users.ordering的附加列,该列始终返回0,上面没有列出-我正在使用它为没有event_id的歌曲赋予0值。

SELECT name, artist, title, users.ordering AS event_id
FROM users, song_history, song_current
WHERE users.id = song_history.singer_id
AND song_history.song_id = songs.id
AND users.id = '2'
UNION
SELECT name, artist, title, song_current.event_id AS event_id
FROM users, song_current, songs
WHERE users.id = song_current.singer_id
AND song_current.song_id = songs.id
AND users.id = '2'
AND song_current.event_id = '20'

请记住,此UNION查询有效,但有一个例外(尽管我可以接受),它为event_id为0的用户列出了song_history中的所有歌曲,然后再次列出了song_history和song_current以及匹配的event_id。 该结果将与上面列出的结果一样可接受。

您可能需要做的就是删除event_id上的过滤条件,或者也包括NULL event_id,如下所示

SELECT name, artist, title, 
CASE
  WHEN event_id <> 20 THEN NULL
  ELSE event_id
END event_id
FROM users AS user
LEFT JOIN song_history AS history ON user.id = history.singer_id
LEFT JOIN songs AS song ON history.song_id = song.id
LEFT JOIN song_current AS csongs ON csongs.singer_id = user.id
AND csongs.song_id = history.song_id
WHERE user.id = 2

SQL Fiddle演示第三个查询包括具有NULL event_id的行。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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