需要帮助构建具有一个特定结果+随机结果的查询


need help to construct a query with one certain result + random result

我需要帮助如何构建一个查询,将根据一个条件返回5个结果。
在这5个结果中,如果查询中指定了其中一条记录,则必须始终出现。
剩下的将随机抽取。

我有表格国家,类别,问题
对于国家,我有记录:加拿大,中国,法国,德国,日本,美国
第一类有记录:首都、地标、旗帜、语言

每个问题都根据类别和国家进行分类。
现在,当我选择一个国家时,我想要一个类别为"CAPITAL"的问题总是出现在结果中。
因此,如果我选择FRANCE,必须选择5个关于FRANCE的问题,其中一个结果具有CAPITAL类别,其他4个是随机选择的。

我的解决方案是有两个问题,但我不知道它是否正确:

SELECT * FROM QUESTIONS WHERE COUNTRY = "FRANCE" AND CATEGORY = "CAPITAL"

SELECT * FROM QUESTIONS WHERE COUNTRY = "FRANCE" AND CATEGORY != "CAPITAL" ORDER BY RAND() LIMIT 4

然后添加结果。
我还从某处听说使用RAND()函数有一个缺点,因为它必须在选择随机记录之前对记录进行排序。因此,如果您有数千条记录,则不适合使用。
因此,如果有更好的方法来做到这一点,如果有人可以帮助,我将非常感激。

为什么不添加另一列来表示该行具有更高的优先级呢?

Select * from Colors order by priority DESC, Rand() limit 5

或者如果有非常特殊的条件,可以这样编码:

SELECT * FROM Colors
ORDER BY IF(ColorName = 'Green', 100, IF(_other_conds_if_any_, 99, 0)) DESC,
    Rand()
LIMIT 5

我一直建议同样的解决方案。好吧,我再详细解释一下。在我看来,最好的办法是在你的表中添加一列"sticky"(在你的情况下是QUESTIONS)。

ALTER TABLE `QUESTIONS` ADD COLUMN `sticky` TINYINT NOT NULL DEFAULT 0;

然后将需要的问题标记为sticky(为此制作管理UI或自己运行原始查询)

UPDATE `QUESTIONS` SET `sticky` = IF(`CATEGORY` = "CAPITAL", 1, 0);

然后像这样选择你的问题:

SELECT *
FROM `QUESTIONS`
WHERE `COUNTRY` = "FRANCE"
ORDER BY `sticky` DESC, RAND()
LIMIT 5;

最好做一个管理UI来指定什么问题是粘性的条件,并在添加问题后运行它。这有利于频繁选择。如果经常添加新问题,那么最好将条件直接放入ORDER子句中(然后不需要添加该列),或者将该列添加到类别表中并JOIN它。

#1. don't add any column and put condition into ORDER clause
SELECT *
FROM `QUESTIONS`
WHERE `COUNTRY` = "FRANCE"
ORDER BY IF(`CATEGORY` = "CAPITAL", 1, 0) DESC, RAND()
LIMIT 5;
#2. add column to categories table
SELECT q.*
FROM `QUESTIONS` q
    INNER JOIN `CATEGORIES` cat ON (cat.`CATEGORY_NAME` = q.`CATEGORY`)
    #unsure what your conditions would be here as Idon't know your DB structure
WHERE q.`COUNTRY` = "FRANCE"
ORDER BY cat.sticky DESC, RAND()
LIMIT 5;

这是非常类似于你有,但它看起来很好,我:

Select * from Colors where ColorName = 'Green'
UNION
SELECT * FROM (Select * from Colors where ColorName != 'Green' order by Rand() limit 4)

另一种方法是在查询中使用CASE语句:

SELECT *,
  CASE ColorName
    WHEN 'green' THEN 2
    ELSE RAND()
  END AS r
FROM Colors ORDER BY r DESC LIMIT 5

但我猜做两个查询实际上更快。