我的查询当前返回的数据具有以下属性:
示例:
+--+-+-+
|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 - 它可以在两者之间或之间的任何位置。< / p>
答案 0 :(得分: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
DEMO (SQL小提琴)。
答案 1 :(得分: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
答案 2 :(得分: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 ;