如何更新结果集的计数器

时间:2010-07-10 18:59:01

标签: sql mysql

我正在创建类似于广告系统的东西。 我想展示一个给定数据库表中的5个广告(5个记录)。 所以我执行类似

的操作
SELECT * FROM mytable 
ORDER BY view_counter ASC
LIMIT 5
好的,它有效。 但是,如何使用单个SQL来contextualy更新“view_counter”(即具有show数量的计数器)? 并且,如果我不要求太多,是否可以保存我的记录返回的“位置”? 例如,我的s​​ql返回

- record F   (pos. 1)
- record X   (pos. 2)
- record Z   (pos. 3) 

并在“Avarage_Position”字段中保存... avarage of position?

提前致谢。

此致

3 个答案:

答案 0 :(得分:1)

  

如何使用单个SQL上下文更新“view_counter”(即具有show数的计数器)?

这通常由分析/排名/窗口函数处理,MySQL目前不支持。但您可以使用以下查询来获取所需的输出:

  SELECT *,
         @rownum := @rownum + 1 AS rank
    FROM mytable 
    JOIN (SELECT @rownum := 1) r
ORDER BY view_counter ASC
   LIMIT 5

你会得到如下输出:

description  |  rank
--------------------------
record F     |  1
record X     |  2
record Z     |  3

  

如果我不要求太多,是否可以保存我的记录被退回的“位置”?

我不建议这样做,因为这意味着每次发生变化时都需要更新数据。在其他数据库上,我建议使用视图,以便仅在使用视图时进行计算,但MySQL不支持在视图中使用变量。

有另一种方法可以使用子选项获取排名值 - this link is for SQL Server, but there's nothing in the solution that is SQL Server specific

答案 1 :(得分:0)

你可以做这样的事情,但它很丑陋,我不推荐它(见下面我的实际建议如何处理这个问题)。
创建一个dummy_field tinyint字段,sum_position int字段和average_position十进制字段,并在同一连接中运行以下几个语句(我通常非常反对MySQL存储过程,但在这种情况下,将它存储在SP中可能很有用)。

SET @updated_ads := '';
SET @current_position := 0;
UPDATE mytable SET view_counter= view_counter+1, 
    dummy_field = (SELECT @updated_ads := CONCAT(@updated_ads,id,"\t",ad_text,"\r\n"))*0, /* I added *0 for saving it as tinyint in dummy_field */
    sum_position = sum_position + (@current_position := @current_position +1),
    average_position = sum_position / view_counter
ORDER BY view_counter DESC
LIMIT 5;
SELECT @updated_ads;

然后使用您使用的分隔符解析代码中的结果字符串(我使用\ r \ n作为行分隔符,\ t \ t作为字段分隔符)。

我实际建议你做的是:

  • 查询所选广告。
  • 使用选定的广告和位置撰写日志文件。
  • 编写作业以处理日志文件并批量更新view_counter,average_position和sum_position字段。

答案 2 :(得分:0)

谢谢你的回答。我解决了简单地执行相同的SELECT查询(完全是WHERE,Order BY和LIMIT子句)但是,相反,我使用了UPDATE。 是的,这是一个“开销”,但这是一个简单的解决方案。