2013-05-11 2 views
0

나는 라디오 방송국 재생 목록을 생성하는 웹 서비스를 가지고 있으며 재생 목록에 n 번 이상의 동일한 아티스트의 트랙이 없도록 보장하려고합니다.제한에 의한 SQLite 그룹

예를 들어 (Mandatory Metallica - 하하가 아니면) 아티스트는 8 시간 프로그래밍 세그먼트를 지배해서는 안됩니다.

오늘 우리는 기존의 대규모 재생 목록에서 작은 무작위 재생 목록을 생성하는 다음과 유사한 쿼리를 사용 :

SELECT FilePath FROM vwPlaylistTracks 
WHERE Owner='{0}' COLLATE NOCASE AND 
Playlist='{1}' COLLATE NOCASE 
ORDER BY RANDOM() 
LIMIT {2}; 

누군가 다음 같은 작가가 연속적으로 나타나는 경우 수동으로 재생 목록을 검토하고 일부 수동 편집을 할 수있다 또는 원하는 한계보다 커야합니다.

제작자가이 쿼리에서 생성 된 재생 목록의 범위에 아티스트가 두 번 이상 표시되지 않도록하려는 경우 (그리고 vwPlaylistTracks보기에 아티스트 필드가 있다고 가정 할 경우) 올바른 GROUP BY가 GROUP BY입니다. 이것을 성취하기 위해서?

나는이 일을 성취하려고 노력하고 있지만이 쿼리는 항상 각 아티스트의 1 트랙 만 반환합니다.

SELECT 
    a.Name as 'Artist', 
    f.parentPath || '\' || f.fileName as 'FilePath', 
    p.name as 'Playlist', 
    u.username as 'Owner' 
FROM mp3_file f, 
    mp3_track t, 
    mp3_artist a, 
    mp3_playlist_track pt, 
    mp3_playlist p, 
    mp3_user u 
WHERE f.file_id = t.track_id 
AND t.artist_id = a.artist_id 
AND t.track_id = pt.track_id 
AND pt.playlist_id = p.playlist_id 
AND p.user_id = u.user_id 
--AND p.Name = 'Alternative Rock' 
GROUP BY a.Name 
--HAVING Count(a.Name) < 3 
--ORDER BY RANDOM() 
--LIMIT 50; 

답변

2

GROUP BY 정확히 그룹화 열의 각 구별 값에 대한 하나 개의 결과 레코드를 작성, 그래서 이것은 당신이 원하는 없습니다.

동일한 아티스트의 이전의 개의 레코드 수를 계산해야합니다. 이는 임의 순서가 안정되지 않아 쉽지 않습니다. 그러나,이는 rowid으로 정렬 된 임시 테이블, 가능합니다 :

CREATE TEMPORARY TABLE RandomTracks AS 
SELECT a.Name as Artist, parentPath, name, username 
FROM ... 
WHERE ... 
ORDER BY RANDOM(); 
CREATE INDEX RandomTracks_Artist on RandomTracks(Artist); 

SELECT * 
FROM RandomTracks AS r1 
WHERE -- filter out if there are any two previous records with the same artist 
     (SELECT COUNT(*) 
     FROM RandomTracks AS r2 
     WHERE r2.Artist = r1.Artist 
     AND r2.rowid < r1.rowid 
    ) < 2 
    AND -- filter out if the directly previous record has the same artist 
     r1.Artist IS NOT (SELECT Artist 
         FROM RandomTracks AS r3 
         WHERE r3.rowid = r1.rowid - 1) 
LIMIT 50; 

DROP TABLE RandomTracks; 

이 쉽고 단지 전체 재생 목록을 읽기 및 필터링 코드에 순서를 빠르게 할 수 있습니다.

+0

고마워요! 나는 이것을 가지고 놀 것이다. 귀하가 옳다고 생각합니다. 비즈니스 규칙을 코드에 적용하는 것이 훨씬 쉬울 수도 있습니다. 솔루션이 SQL에서 더 단순하다면 코드에서 복잡한 알고리즘을 고안하고 싶지는 않지만, 그렇지 않을 수도 있습니다. –