如何在选择中返回表示已找到ID的字段?
我的目标是从特定来源(来源)返回所有歌曲(歌曲),检查用户(用户)是否拥有(user_song)。
我所做的查询几乎可以正常工作。如果我删除了'hasSong' (我试图表明用户是否有歌曲),我可以看到所有歌曲。
如果我保持' hasSong',我会看到所有歌曲都为每个用户重复歌曲。
QUERY:
SELECT DISTINCT(song.id) AS id_song, CONCAT(song.article, ' ', song.name) AS name
FROM `song`
LEFT JOIN `user_song` ON `song`.`id` = `user_song`.`id_song`
LEFT JOIN `user` ON `user`.`id` = `user_song`.`id_user`
JOIN `song_source` ON `song`.`id` = `song_source`.`id_song`
WHERE `song_source`.`id_source` = '1'
AND ( `user_song`.`id_user` = '3' OR song.id = song_source.id_song )
ORDER BY `song`.`name` ASC
DB:
CREATE TABLE `song` (
`id` int(11) NOT NULL,
`article` varchar(10) NOT NULL,
`name` varchar(150) NOT NULL,
`shortname` varchar(150) NOT NULL,
`year` int(11) NOT NULL,
`artist` int(11) NOT NULL,
`duration` int(11) NOT NULL,
`genre` int(11) NOT NULL,
`updated` int(11) NOT NULL
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
CREATE TABLE `song_source` (
`id_song` int(11) NOT NULL,
`id_source` int(11) NOT NULL
)
CREATE TABLE `source` (
`id` int(11) NOT NULL,
`article` varchar(10) NOT NULL,
`name` varchar(150) NOT NULL,
`updated` int(11) NOT NULL
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
CREATE TABLE `user` (
`id` int(11) NOT NULL,
`email` varchar(100) NOT NULL,
`password` varchar(255) NOT NULL
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
CREATE TABLE `user_song` (
`id_user` int(11) NOT NULL,
`id_song` int(11) NOT NULL
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
答案 0 :(得分:1)
规范并不完全清楚,......
要返回来自特定来源(song.id
)的所有歌曲(没有重复的id_source='1'
值),
以及一个指标,值为0或1,告诉我们user_song
中的id_song
行是否与id_user = '3'
匹配且与特定用户相关,({{ 1}})
类似的东西:
SELECT s.id AS id_song
, MAX( CONCAT(s.article,' ',s.name) ) AS name
, MAX( IF(us.id_user = '3' ,1,0) ) AS has_song
FROM `song` s
JOIN `song_source` ss
ON ss.id_song = s.id
AND ss.id_source = '1'
LEFT
JOIN `user_song` us
ON us.id_song = s.id
AND us.id_user = '3'
GROUP BY s.id
ORDER BY MAX(s.name)
还有一些其他查询模式会返回相同的结果。例如,我们可以在SELECT列表中使用相关子查询。
SELECT s.id AS id_song
, MAX( CONCAT(s.article,' ',s.name) ) AS name
, ( SELECT IF( COUNT(us.id_user) >0,1,0)
FROM `user_song` us
WHERE us.id_song = s.id
AND us.id_user = '3'
) AS has_song
FROM `song` s
JOIN `song_source` ss
ON ss.id_song = s.id
AND ss.id_source = '1'
GROUP BY s.id
ORDER BY MAX(s.name)
由于在任何表中都不保证唯一性,因此这些查询很复杂。如果我们有保证,我们就可以省去GROUP BY
和聚合函数。
请考虑在表上添加PRIMARY和/或UNIQUE KEY约束,以防止重复。定义表的方式,我们可以向song
添加多行,并使用相同的id
值。 (那些可能有不同的name
值。)
(如果我们有一些唯一性的保证,那么查询将会更简单。)