3

我有一个查询当前返回具有以下属性的数据:

  • 一个数字A保证在结果中是唯一的(不在源表中);结果按 A 排序,但结果中 A 的值不一定是连续的。
  • 对多行重复的键B,将它们标记为同一组的一部分。它来自与 A 相同的表。

例子:

+--+-+-+
|id|A|B|
+--+-+-+
| 5|1|2|
|15|3|2|
|12|4|5|
|66|6|5|
| 2|7|2|
+--+-+-+

我在这里看到了解释如何在结果中返回行号的答案。但是,我需要的是获得一个(最好是基于 1 的)订单号,同时为每个B保持不同的计数。在下表中,C是期望的结果:

+--+-+-+-+
|id|A|B|C|
+--+-+-+-+
| 5|1|2|1|
|15|3|2|2|
|12|4|5|1|
|66|6|5|2|
| 2|7|2|3|
+--+-+-+-+

这超出了我目前的 SQL 技能,所以我会感谢任何指针。包括指向现有答案的指针!

编辑:下面的两个答案在结果方面同样有效(使用虚拟包装查询进行排序)。谢谢大家的帮助。哪个是最有效的查询?考虑到在我的特定用例中,从原始查询返回的行数永远不会很大(假设最多 50 行,即使这是想象的延伸)。此外,原始查询具有用于从其他关系中获取数据的连接,尽管它们与排序或过滤无关。最后,所有结果都可能具有相同的B,或者每个结果都具有不同的B ——它可以是任何一种方式,也可以是介于两者之间的任何地方。

4

3 回答 3

6

您基本上想要的是RANK()功能。但是,由于它在 MySQL 中不可用,您可以使用以下方法模拟它:

SELECT *
FROM (
  SELECT a, b, (CASE b 
                WHEN @partition THEN @rank := @rank + 1 
                ELSE @rank := 1 AND @partition := b END) AS c
  FROM tbl, (SELECT @rank := 0, @partition := '') tmp
  ORDER BY b, a
) tmp
ORDER BY a

演示(SQL 小提琴)。

于 2012-08-24T12:16:10.503 回答
4
select p.*, @i := if(@lastB != p.B, 1, @i + 1)
,@lastB := p.B as B
from table_name p, 
(select @i := 0) vt1,
(select @lastB := null) vt2
order by B;

试试这个代码。(未测试)

使用 sqlfiddle http://sqlfiddle.com/#!2/412df/13/2编辑演示

于 2012-08-24T12:15:04.450 回答
0

这不会非常有效,因为您的查询必须计算两次,然后还要进行分组:

SELECT 
    q.* ,
    COUNT(*) AS c              --- the "Rank"
FROM 
    yourQuery AS q
  JOIN
    yourQuery AS qq
      ON  qq.B = q.B
      AND qq.A <= q.A
GROUP BY
    q.A ;
于 2012-08-24T12:20:36.020 回答