如何使用值为圆形的列(即1,2,3,1,2,3,1,2,3 ....)来计算并输出循环的索引号? 例如,在这个简化的表格中......
num cir
1 1
2 2
3 3
4 1
5 2
6 3
7 1
8 2
9 3
我怎么能得到这个?
num cir index
1 1 1
2 2 1
3 3 1
4 1 2
5 2 2
6 3 2
7 1 3
8 2 3
9 3 3
实际上,我试图管理的表格要大得多(数百万条记录乘以160列),所以如果有多种解决方案,我希望听到更有效的解决方案......谢谢。
答案 0 :(得分:3)
Gordon Linoff is right:在SQL中,表确实没有固有的顺序。但是,仍然有一种方法可以为您的案例分配索引。唯一的问题是,订单是不确定的,1可能与2组合在一起,不一定是跟随它的2(按照您可能期望的任何特定顺序)。也就是说,最终结果可能与您的示例相似:
num cir index
--- --- -----
1 1 1
2 2 1
3 3 1
4 1 2
5 2 2
6 3 2
7 1 3
8 2 3
9 3 3
但很可能是例如相反:
num cir index
--- --- -----
7 1 1
2 2 1
3 3 1
4 1 2
8 2 2
6 3 2
1 1 3
5 2 3
9 3 3
如果num
没有“井然有序”,就像你说的那样(因此,我假设,不能用于排序)。
我们的想法是仅对cir
列上的数据集进行排序
num cir
--- ---
1 1
4 1
7 1
2 2
5 2
8 2
3 3
6 3
9 3
然后使用变量赋值生成index
值
num cir index
--- --- -----
1 1 1 1
4 1 2 2
7 1 3 3
2 2 1 -> 1
5 2 2 2
8 2 3 3
3 3 1 1
6 3 2 2
9 3 3 3
以下是:
SELECT
num,
cir,
`index`
FROM (
SELECT
num,
@index := @index * (cir = @lastcir) + 1 AS `index`,
@lastcir := cir AS cir
FROM
yourtable,
(SELECT @index := 0, @lastcir := 0) v
ORDER BY
cir
) s
ORDER BY
`index`,
cir
;
可以猜到,这个表达
@index := @index * (cir = @lastcir) + 1
是指定索引的那个。基本上,如果您删除* (cir = @lastcir)
部分,则会获得
@index := @index + 1
可能不需要解释:它只是递增@index
值。
每次遇到新的cir
值时,都会重置枚举(请记住,数据集是在cir
上排序的)。在MySQL中,布尔表达式(如cir = @lastcir
)隐式转换为期望数字的上下文中的数字,如算术表达式的上下文。更具体地说,它转换为1
的{{1}}和true
的{{1}}。因此,只要0
等于false
(即前一行cir
),@lastcir
表达式基本上等同于cir
,但{ {1}}和index
不同(这意味着我们刚遇到一个新的@index := @index + 1
组),表达式实际上变为cir
,即枚举现在重新开始。< / p>
如果您愿意,可以测试此解决方案at SQL Fiddle。
答案 1 :(得分:1)
假设num1
是有序的(尽管可能存在间隙),解决此问题的一种方法是根据找到的循环数的次数来分配索引,以获得较小的{{1}值}}。我认为在MySQL中最明智的方法是使用相关的子查询:
num
如果未订购select t.*,
(select count(*) from t t2 where t2.cir = t.cir and t2.num <= t.num
) as `index`
from t
,则表示您遇到问题。 SQL表本质上是无序的,因此给定行没有“之前”和“之后”的概念。也就是说,除非您有某种方式对结果进行排序,否则没有一种强大的方式来分配索引。
答案 2 :(得分:0)
尝试使用非下一个cirsakes进行自我加入并计算它们:
SELECT t1.num AS num, t1.cir AS cir, COUNT(*) AS index
FROM t AS t1 JOIN t AS t2 on t2.cir = t1.cir AND t2.num <= t1.num
GROUP BY t1.num, t1.cir
;
答案 3 :(得分:0)
试试这个
SELECT
num,
cir,
@row_num := IF(@prev_cir<cir,@row_num,@row_num+1) as cir_index,
@prev_cir:= cir
FROM
(SELECT @row_num := 0) r
JOIN (
SELECT
num,
cir
FROM
mytable
ORDER BY
num
) t
首先,我确保记录按num
排序。然后我知道前一个cir
与当前的cir
。如果之前的cir_index
大于当前{{1}},我会增加{{1}}