如何确保未选择数据库中具有相同编号的两行?

时间:2017-06-09 16:44:10

标签: php mysql mysqli logic

我每天都在为一个评级网站运行一个cronjob,该网站运行一个脚本,从每个类别中选择3个随机图像,然后访问者可以相互评价图像,如“图像1与图像2 - >您喜欢哪一个最好的“,这很有效。

问题是我们可以说有两种相同类型的图像

我们假设

  • id 1是福特野马GT前视图
  • id 2是福特野马GT前视图,与id 1
  • 略有不同

这是一个问题,因为如果同时选择了id 1和id 2,那么就像说两个完全相同的图像相互对立?所以我创建了一个“分隔符列”,其中我给出了代表相同数字的图像,所以在这个简化的情况下,id 1和id 2都有分隔符号1:)

数据库结构

Table Cars

cars_id | cars_category | cars_source   | separator
--------+---------------+---------------+-----------
1       |    1          | 123.jpg       | 1
2       |    1          | 242.jpg       | 1
3       |    2          | 532.jpg       | 2
4       |    2          | 531.jpg       | 3
5       |    2          | 45fd.jpg      | 3
6       |    3          | da3.jpg       | 4

当前PHP脚本,从每个类别中选择3个随机图像

$cat1 = 1;
$cat2 = 2;
$cat3 = 3;
$stmt = $dbCon->prepare(" INSERT INTO daily_versus ( daily_versus_source, daily_versus_category) "
        . " (SELECT cars_source, cars_category "
        . " FROM cars "
        . " WHERE cars_category IN (?) ORDER BY RAND() LIMIT 3) "
        . " UNION "
        . " (SELECT cars_source, cars_category "
        . " FROM cars "
        . " WHERE cars_category IN (?) ORDER BY RAND() LIMIT 3) "
        . " UNION "
        . " (SELECT cars_source, cars_category "
        . " FROM cars "
        . " WHERE cars_category IN (?) ORDER BY RAND() LIMIT 3) ");
$stmt->bind_param('iii', $cat1, $cat2, $cat3);
if ($stmt->execute()) {
    echo "Success VERSUS/INSERT";
} else {
    echo "Fail VERSUS/INSERT";
}

以上作为一种魅力,但是最好的方法是整合分离器数字,这样两辆相同的汽车就无法选择......所以基本上如果选择了分离器编号为“x”的汽车,脚本可以没有选择另一辆具有相同分隔号的汽车?

2 个答案:

答案 0 :(得分:0)

最简单的方法是按分隔符对每个查询进行分组。

...
(SELECT cars_source, cars_category 
 FROM cars 
 WHERE cars_category IN (?) 
 GROUP BY SEPARATOR
 ORDER BY RAND() LIMIT 3) 
...

mysql将从每个组中获取“随机”值。 然而,它并不是真正随机的,对于每个分隔符组,只要选择了该分隔符,它就可能只占用一个(并且始终是相同的)值。

更好 ( - 在使用前开始评论/剥离)

...
(SELECT cars_source, cars_category 
 FROM 
 (select 
    (select id     -- one random id, for each of the 3 random separators
     from cars 
     where separator = ocars.separator -- will be a diff separator for each row in the outer query
     order by rand() limit 1
    ) as rand_id
  from cars as ocars 
  WHERE cars_category IN (?) 
  group by separator   -- each separator only once
  order by rand()      -- random separators
  limit 3              -- 3 random separators
) as cars_id
left join cars on cars.id = cars_id.rand_id   -- join the full row for each rand_id
) 
...

你应该在id和分隔符上有索引, 也许也是类别

答案 1 :(得分:-1)

按[分隔符]排名并选择最上面的一个。