Transact-SQL排名(排序)原始投票

时间:2013-01-07 21:03:12

标签: tsql sorting ranking

我在开发一种算法来对原始投票进行排序时遇到困难。投票表如下所示:

CREATE TABLE [dbo].[Votes](
  RecordId int IDENTITY(1,1) NOT NULL,
  FirstNameId int NOT NULL,
  SecondNameId int NOT NULL,
  FirstPreferred bit NULL)

FirstNameId和SecondNameId是对同一Names表的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 个答案:

答案 0 :(得分: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。第二个选择加入名称表,也包括非投票。