我试图创建一个分类器,允许我根据用户的排名及其偏好获得唯一可能的偏好
我不确定从哪里开始。下面你会看到我正在看的简化版本的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);
根据下表,如果我运行分拣机,我们应该看到显示如下的结果。理想情况下,我只想根据用户的偏好和排名来显示用户获得的项目。
答案 0 :(得分:1)
我能够为您提供一个可行的解决方案,但它远非完美:使用像我在这里做的WHILE
循环打破了SQL优化的基本规则之一,即工作使用基于集合的查询而不是RBAR。尽管如此,我尝试使用CTE
,ROW_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