2

我有一个 select 语句:select a, b, [...];它返回结果:

a|b
---------
1|8688798
2|355744
4|457437
7|27834

我希望它返回:

a|b
---------
1|8688798
2|355744
3|0
4|457437
5|0
6|0
7|27834

一个示例查询不符合我的要求,因为它没有间隙编号:

select
    sub.num_of_ratings,
    count(sub.rater)
from
(
    select 
        r.rater_id as rater,
        count(r.id) as num_of_ratings
    from ratings r
    group by rater
) as sub
group by num_of_ratings;

查询说明:如果一个用户对另一个用户进行评分,评分列在 rating 表中,评分用户的 id 保存在字段 rater_id 中。实际上,我检查了评分中提到的所有用户,并计算了我为该用户找到了多少评分记录,即rater / num_of_ratings,然后我使用此结果来查找有多少用户对给定次数进行评分。

最后我知道有多少用户评价过一次,有多少用户评价过两次,等等。我的问题是 count(sub.rater) 的数字从 1,2,3,4,5 开始很好......但是,对于更大的数字有差距。这是因为可能有一位用户评分 1028 次 - 但没有用户评分 1027 次。

我不想应用存储过程循环结果或类似的东西。是否可以在不使用存储过程、循环或创建临时表的情况下填补结果中的这些空白?

4

3 回答 3

3

如果您有一个数字序列,那么您可以对该表执行 JOIN 并正确填充空白。

您可以查看有关如何获取序列的问题: 在 MySQL 中生成整数序列

这是发布的答案之一,可能很容易使用生成从 1 到 10,000 的数字的限制:

SELECT @row := @row + 1 as row FROM 
(select 0 union all select 1 union all select 3 union all select 4 union all select 5 union all select 6 union all select 6 union all select 7 union all select 8 union all select 9) t,
(select 0 union all select 1 union all select 3 union all select 4 union all select 5 union all select 6 union all select 6 union all select 7 union all select 8 union all select 9) t2, 
(select 0 union all select 1 union all select 3 union all select 4 union all select 5 union all select 6 union all select 6 union all select 7 union all select 8 union all select 9) t3, 
(select 0 union all select 1 union all select 3 union all select 4 union all select 5 union all select 6 union all select 6 union all select 7 union all select 8 union all select 9) t4, 
(SELECT @row:=0) t5
于 2012-06-21T15:45:50.150 回答
0

使用一系列数字,您可以加入您的结果集。例如,假设您的号码列表位于名为 numbersList 的表中,列号为:

Select number, Count 
from
  numbersList left outer join
  (select
      sub.num_of_ratings,
      count(sub.rater) as Count
  from
  (
      select 
          r.rater_id as rater,
          count(r.id) as num_of_ratings
      from ratings r
      group by rater
  ) as sub
  group by num_of_ratings) as num

on num.num_of_ratings=numbersList.number
where numbersList.number<max(num.num_of_ratings) 

显然,您的数字列表必须大于您的最大值,并且该限制将允许它没有所有数字都达到最大值。(如果 MySQL 不允许这种类型的 where 子句,您可以不使用 where 子句以列出所有数字直到最大值,或者以各种方式修改查询以获得相同的结果。)

于 2012-06-21T17:20:17.203 回答
0

@mazzucci:查询太神奇了,您实际上并没有解释查询。

@David:我不能为此目的创建一个表(如问题中所述)

基本上我需要的是一个返回无间隙数字列表的选择。然后我可以在该结果集上留下连接并将 NULL 视为 0。

我需要的是一个任意表,它保存的记录多于最终列表的长度。我在以下示例中使用表用户:

select @row := @row + 1 as index
    from (select @row := -1) r, users u
limit 101;

此查询返回一组从 0 到 100 的数字。将其用作左连接中的子查询最终填补了空白。

users 只是保持关系引擎运行并因此逐步生成数字的假人。

select t1.index as a, ifnull(t2.b, 0) as b
from (
    select @row := @row + 1 as index
        from (select @row := 0) r, users u
    limit 7
) as t1
left join (
    select a, b [...]
) as t2
on t1.index = t2.a;

我没有现场尝试这个查询,所以如果有一点缺陷,请与我一起感谢。但从技术上讲它有效。你明白我的意思。

编辑:

只是使用这个概念来获得一个无缝的日期列表,以便在其上留下连接度量:

select @date := date_add(@date, interval 1 day) as date
    from (select @date := '2010-10-14') d, users u
limit 700

从 2010/10/15 开始,再迭代 699 天。

于 2012-07-03T10:00:02.507 回答