我是SQL的新手,我有一个包含两列的SQL数据库,这两列的组合是唯一的(但它们的单个值不是):songID
和artistID
。每首歌曲是由不同的歌手录制的,每位歌手录制的歌曲都是不同的(请参见下面的代码)。我现在想提取有关谁与谁合作的信息。
我尝试过
SELECT songID, COUNT(songID) FROM mytable
GROUP BY artist ID;
但这并不能完全给我想要的结果。
考虑以下示例代码:
CREATE TABLE "mytable" ("songID" int, "artistID" int);
INSERT INTO mytable ('songID', 'artistID') VALUES (1, 101), (1, 102), (1, 103), (2, 102), (2, 103), (3, 101), (3, 104);
通过查看歌曲ID,可以从逻辑上获得所需的结果,例如:songID
= 1:artistID
s = {101, 102, 103}
,因此艺术家101
拥有一首普通歌曲,歌手102
和歌手103
的一首歌,以及歌手102
与歌手103
的一首共同歌曲。 (对每个songID
重复一次)。因此,所需的结果如下所示:
"artist combinations" "count"
"101 & 102" 1
"101 & 103" 1
"101 & 104" 1
"102 & 103" 2
"102 & 104" 0
"103 & 104" 0
理想情况下,我将其按照count
进行排序。有人可以指出我正确的方向吗?
答案 0 :(得分:1)
一些CTE可以帮助生成所有可能和现有的艺术家组合。
一旦获得了两者,就可以将现有的加入可能的连击中。
CREATE TABLE mytable ( songID int not null, artistID int not null, primary key (songID, artistID) );
INSERT INTO mytable (songID, artistID) VALUES (1, 101), (1, 102), (1, 103), (2, 102), (2, 103), (3, 101), (3, 104);
WITH ARTISTS AS ( SELECT DISTINCT artistID FROM mytable ) , ARTISTCOMBOS AS ( SELECT a1.artistID AS artistID1, a2.artistID AS artistID2 FROM ARTISTS a1 JOIN ARTISTS a2 ON a2.artistID > a1.artistID ) , SONGARTISTCOMBOS AS ( SELECT t1.artistID AS artistID1, t2.artistID AS artistID2, COUNT(DISTINCT t1.songID) AS TotalSongs FROM mytable t1 JOIN mytable t2 ON t2.songID = t1.songID AND t2.artistID > t1.artistID GROUP BY t1.artistID, t2.artistID ) SELECT a.artistID1 ||' & '|| a.artistID2 as "artist combinations", COALESCE(sa.TotalSongs, 0) AS "Count" FROM ARTISTCOMBOS a LEFT JOIN SONGARTISTCOMBOS sa ON sa.artistID1 = a.artistID1 AND sa.artistID2 = a.artistID2 ORDER BY a.artistID1, a.artistID2
artist combinations | Count :------------------ | :---- 101 & 102 | 1 101 & 103 | 1 101 & 104 | 1 102 & 103 | 2 102 & 104 | 0 103 & 104 | 0
db <>提琴here
答案 1 :(得分:1)
欢迎使用sql和stackoverflow!
以下代码将起作用,尽管不会给您零协作。如果需要零,请使用外部联接替换简单选择。注意避免重复计算(这就是select aa.twoartists, count(aa.songID) from (
select CONCAT(CAST(a1.artistID as CHAR)," & ",CAST(a2.artistID as CHAR)) as twoartists,
a1.artistID as artist1, a2.artistID as artist2, a1.songID
from mytable a1, mytable a2
where a1.songID = a2.songID and a1.artistID < a2.artistID) aa
group by aa.twoartists;
答案 2 :(得分:1)
这有招:
console.log(
"I´m a little tea pot".replace(/\b\w/g, word => word.toUpperCase())
);
P.S。我不熟悉sqlite语法,但是认为这应该可行。
答案 3 :(得分:0)
这将为您提供所需的结果,而不会出现艺术家之间没有共同歌曲的情况:
select step_id,
step_name
from msdb.dbo.sysjobhistory
where step_id = 9999
if @@ROWCOUNT = 0
SELECT 123456 AS [step_id], 'There are no step_id matching the WHERE clause' AS [step_name]
请参见demo
结果:
select
min(t.artistid, tt.artistid) || ' & ' ||
max(t.artistid, tt.artistid) "artist combinations",
count(distinct t.songid) "count"
from mytable t left join mytable tt
on tt.songid = t.songid and tt.artistid <> t.artistid
group by "artist combinations"
order by "count"
修改:
当艺术家之间没有共同的歌曲时,这也将计算在内:
| artist combinations | count |
| ------------------- | ----- |
| 101 & 102 | 1 |
| 101 & 103 | 1 |
| 101 & 104 | 1 |
| 102 & 103 | 2 |
请参见demo
结果:
select
min(t.artistid, tt.artistid) || ' & ' ||
max(t.artistid, tt.artistid) "artist combinations",
count(distinct t.songid) "count"
from mytable t inner join mytable tt
on tt.songid = t.songid and tt.artistid <> t.artistid
group by "artist combinations"
union all
select distinct
min(t.artistid, tt.artistid) || ' & ' ||
max(t.artistid, tt.artistid) "artist combinations",
0 "count"
from mytable t inner join mytable tt
on tt.artistid <> t.artistid
and (select count(*) from(
select songid from mytable where artistid = t.artistid
intersect
select songid from mytable where artistid = tt.artistid
)) = 0
order by "count"