通过选择和排名对用户首选项进行排序

时间:2014-09-19 01:24:50

标签: sql sql-server

概述

我试图创建一个分类器,允许我根据用户的排名及其偏好获得唯一可能的偏好

我不确定从哪里开始。下面你会看到我正在看的简化版本的SQL小提琴。

http://sqlfiddle.com/#!3/40f0c5/1/0

初始代码

CREATE TABLE selections
    (
     id int,
     item_id int, 
     preference int
    );
CREATE TABLE ranks
    (
     id int, 
     rank int
    );

INSERT INTO selections
(id, item_id, preference)
VALUES
(14063, 1, 1),
(14063, 2, 2),
(14063, 3, 3),
(15026, 1, 2),
(15026, 2, 1),
(15026, 3, 3),
(25014, 1, 1),
(25014, 2, 2),
(25014, 3, 3);

INSERT INTO ranks
(id, rank)
VALUES
(14063, 1),
(15026, 2),
(25014, 3);

预期结果

根据下表,如果我运行分拣机,我们应该看到显示如下的结果。理想情况下,我只想根据用户的偏好和排名来显示用户获得的项目。

  1. 14063(1) - 第(1)项
  2. 15026(2) - 第(2)项
  3. 25014(3) - 第(3)项

1 个答案:

答案 0 :(得分:1)

我能够为您提供一个可行的解决方案,但它远非完美:使用像我在这里做的WHILE循环打破了SQL优化的基本规则之一,即工作使用基于集合的查询而不是RBAR。尽管如此,我尝试使用CTEROW_NUMBER()以及一些NOT EXISTS查询来实现此方法,并且由于双重性质,每次都失败了那种。我的WHILE循环非常不起眼,所以希望有人能够出现并为您提出一些改进建议。有很多人在那里,正义的愤慨可能会激起一两个批评 - 希望他们也会抛出一些想法或自己的答案。 :)

有了这个愉快的自我批评的警告,并希望你在表现上好运,这里有一个查询,可以获得所需的结果集:

DECLARE @SortingOutcome TABLE
  (
    UserID INT,
    UserRank INT,
    ItemID INT,
    ItemPreference INT
  )


DECLARE @Looper INT = 1
DECLARE @Ender INT 
SELECT @Ender = MAX(Rank) FROM Ranks

WHILE @Looper <= @Ender
  BEGIN
    INSERT INTO @SortingOutcome
      (
        UserID,
        UserRank,
        ItemID,
        ItemPreference
      )
    SELECT TOP 1
        r.ID,
        rank,
        item_id,
        preference
    FROM 
        Ranks r
         INNER JOIN 
        Selections s ON 
            r.id = s.ID 
    WHERE 
        r.rank = @Looper AND
        NOT EXISTS
          (
            SELECT 1
            FROM @SortingOutcome
            WHERE ItemID = s.item_id
          )
    ORDER BY preference 

    SET @Looper = @Looper + 1
  END

SELECT * FROM @SortingOutcome

SQLFiddle