SQL: оператор условного подсчета - PullRequest
1 голос
/ 26 марта 2019

Я новичок в 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);

Желаемый результат получается логически, глядя на идентификатор песни, например: songID = 1: artistID s = {101, 102, 103}, поэтому у исполнителя 101 есть одна общая песня с исполнителем 102 и одна с исполнителем 103, а Artist 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. Может ли кто-нибудь указать мне правильное направление?

Ответы [ 4 ]

1 голос
/ 26 марта 2019

Это делает свое дело:

select artistid1, artistid2, sum(num) from (
  select s1.songid as songid1, s1.artistid as artistid1, s2.songid as songid2, s2.artistid as artistid2, 
        case when s1.songid = s2.songid then 1 else 0 end as num
  from mytable s1 cross join mytable s2
  where s1.artistid < s2.artistid)
group by artistid1, artistid2
order by artistid1;

PS Я не знаком с синтаксисом sqlite, но думаю, что это должно работать.

1 голос
/ 26 марта 2019

Несколько 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    

дБ <> скрипка здесь

1 голос
/ 26 марта 2019

добро пожаловать в sql и stackoverflow!

Этот следующий код будет работать, хотя и не даст вам ноль сотрудничества.Если вам нужны нули, замените простой выбор внешним соединением.Будьте осторожны, чтобы избежать двойного счета (вот почему оператор <где).Используйте внутренний подзапрос для подтверждения желаемых результатов. </p>

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;
0 голосов
/ 26 марта 2019

Это даст вам необходимые результаты без случаев, когда между исполнителями нет общей песни:

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"

См. demo Результаты:

| artist combinations | count |
| ------------------- | ----- |
| 101 & 102           | 1     |
| 101 & 103           | 1     |
| 101 & 104           | 1     |
| 102 & 103           | 2     |

Редактировать :Это также будет учитываться, если между исполнителями нет общих песен:

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"

См. demo Результаты:

| artist combinations | count |
| ------------------- | ----- |
| 102 & 104           | 0     |
| 103 & 104           | 0     |
| 101 & 102           | 1     |
| 101 & 103           | 1     |
| 101 & 104           | 1     |
| 102 & 103           | 2     |
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...