Transact-SQL ранг (сортировка) необработанных голосов
Я застрял при разработке алгоритма сортировки необработанных голосов. Таблица голосов выглядит так:
CREATE TABLE [dbo].[Votes](
RecordId int IDENTITY(1,1) NOT NULL,
FirstNameId int NOT NULL,
SecondNameId int NOT NULL,
FirstPreferred bit NULL)
FirstNameId и SecondNameId являются ссылками на PK одной и той же таблицы имен. Пользователь голосует парами либо за имя, либо за второе имя, и в зависимости от того, что столбец FirstPreferred принимает значение 1 (True) или 0 (false).
Пожалуйста помоги. Я действительно не придумал ничего лучше, чем навести курсор на таблицу голосов.
Таблица голосов уже заполнена данными, поэтому я не могу влиять на процесс голосования.
Данные голосования:
RecordId FirstNameId SecondNameId FirstPreferred
1 41 60 0
2 49 108 0
3 110 118 0
4 35 41 0
5 15 100 0
6 12 74 1
7 16 122 1
8 46 118 0
9 46 105 1
10 93 117 0
Пример данных из таблицы имен:
NameId Name
5 Nicolas
6 Sergio
11 Alexander
12 Alexei
13 Albert
15 Anatoly
16 Andreas
1 ответ
Если я вас правильно понимаю, вы хотите посчитать, как часто за каждое имя голосовали, а затем вывести результаты, отсортированные по этому количеству? Если это так, вы можете использовать это:
CREATE TABLE dbo.Names(
NameId INT,
FullName NVARCHAR(20)
)
CREATE TABLE [dbo].[Votes](
RecordId int IDENTITY(1,1) NOT NULL,
FirstNameId int NOT NULL,
SecondNameId int NOT NULL,
FirstPreferred bit NULL)
GO
INSERT INTO dbo.Names
VALUES(1,'p1'),
(2,'p2'),
(3,'p3'),
(4,'p4');
INSERT INTO dbo.Votes
VALUES (1,2,1),
(1,3,1),
(1,4,0),
(2,3,1),
(2,4,0),
(3,4,0);
WITH VotedNames AS(
SELECT CASE WHEN FirstPreferred = 1
THEN FirstNameId
ELSE SecondNameId
END AS NameId
FROM dbo.Votes
)
SELECT NameId, COUNT(1) AS Votes
FROM VotedNames
GROUP BY NameId
ORDER BY Votes DESC;
WITH VotedNames AS(
SELECT CASE WHEN FirstPreferred = 1
THEN FirstNameId
ELSE SecondNameId
END AS NameId
FROM dbo.Votes
)
,VoteCounts AS(
SELECT NameId, COUNT(1) AS Votes
FROM VotedNames
GROUP BY NameId
)
SELECT n.*,ISNULL(v.Votes,0) AS Votes
FROM dbo.Names AS n
LEFT JOIN VoteCounts AS v
ON n.NameId = v.NameId
ORDER BY v.Votes DESC;
Первый выбор исключает NameIds, за которые вообще не проголосовали. Второй выбор присоединяется к таблице имен и включает также голосов без голосования.