(如何)我可以在单个查询中按行/结果顺序对查询结果组进行编号?

Pro*_*ted 3 mysql sql select

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

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

例:

+--+-+-+
|id|A|B|
+--+-+-+
| 5|1|2|
|15|3|2|
|12|4|5|
|66|6|5|
| 2|7|2|
+--+-+-+
Run Code Online (Sandbox Code Playgroud)

我在这里看到的答案解释了如何在结果中返回行号.然而,我需要的是获得(优选的基于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|
+--+-+-+-+
Run Code Online (Sandbox Code Playgroud)

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

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

Joã*_*lva 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
Run Code Online (Sandbox Code Playgroud)

DEMO(SQL小提琴).