如何获得"得分列表"对于每个类型的SQL查询?

时间:2013-12-10 01:14:46

标签: mysql

我正在尝试使用我为以下架构的每种类型设计的公式获得一个带有“加权分数”的表格:

收藏:userID,drinkName

历史记录:userID,drinkName

饮料:名称,方向,类型

drinker:idNum,userID,password

让历史上每一杯饮料的价值为0.666分,每种饮品最喜欢的价值为1分。

所以每次让我们说历史记录中显示伏特加类型的饮料0.666应添加到特定用户ID的分子中。 1点为伏特加总计的最爱。 然后它应除以用户ID在收藏夹和历史记录中的总饮料数。

例如,我有3个伏特加历史和2个收藏,它应该是: (3(0.666)2)/ 5

并且查询应该返回所有“类型”的饮料,我有最好的饮料。

我目前有这个查询:

SELECT (
( SELECT COUNT(*)
  FROM   Drink D JOIN History  H ON H.drinkName = D.name
    WHERE  type = 'vodka' AND userID = 'sai') 
+ 
(((SELECT COUNT(*)
    FROM   Drink D JOIN Favorite F ON F.drinkName = D.name
    WHERE  type = 'vodka' AND userID = 'sai'))*0.666))
 /  
((SELECT COUNT(*) FROM History  WHERE userID = 'sai') 
+ 
(SELECT COUNT(*) FROM Favorite WHERE userID = 'sai'))

然而,这仅适用于特定类型的饮品,但不适用于各类饮品。

2 个答案:

答案 0 :(得分:1)

使用GROUP BY和聚合函数来获取每种类型的总数。

SELECT type, SUM(numerator)/SUM(denominator) score
FROM (
    SELECT type, COUNT(*) numerator, COUNT(*) denominator
    FROM History
    WHERE userID = "sai"
    GROUP BY type
    UNION ALL
    SELECT type, (COUNT(*) * 0.666) numerator, COUNT(*) denominator
    FROM Favorites
    WHERE userID = "sai"
    GROUP BY type
) u
GROUP BY type

答案 1 :(得分:0)

我认为你有一点架构问题。似乎没有必要根据用户是否将其标记为收藏而在两个不同的表中跟踪饮料历史。我认为饮料历史记录应该跟踪所有饮料,无论它们是否是最爱,而收藏夹应该只显示该人目前标记为最喜欢的饮料。

所以早些时候拿你的5个饮料的例子,我会说你的桌子看起来像:

历史

userId drinkName someTimeField
sai    vodka     2013-12-09 12:30:53
sai    tequila   2013-12-09 12:31:23
sai    rum       2013-12-09 12:31:53
sai    vodka     2013-12-09 12:32:23
sai    beer      2013-12-09 12:32:53

因此,除了知道Sai可能有饮酒问题(因为你知道他什么时候喝酒),你对他喝的东西有一个完整的了解,不管这些饮料是否是“最爱”

喜爱

userId  drinkNane
sai     vodka
sai     everclear

现在,您只需进行一次简单的连接即可进行计算:

SELECT
    SUM(CASE WHEN f.drinkName IS NOT NULL THEN 1 ELSE 0.66 END CASE)
    /SUM(1) AS `value`
FROM drinker AS d
LEFT JOIN history AS h
  ON d.userId = h.userId
LEFT JOIN favorite AS f
  ON h.userId = f.userId AND h.drinkName = f.drinkName
WHERE d.drinker = ?
GROUP BY d.drinker