我有一个mysql表数据,其中包含以下列
+-------+-----------+----------+
|a | b | c |
+-------+-----------+----------+
| John | 225630096 | 447 |
| John | 225630118 | 491 |
| John | 225630206 | 667 |
| John | 225630480 | 1215 |
| John | 225630677 | 1609 |
| John | 225631010 | 2275 |
| Ryan | 154247076 | 6235 |
| Ryan | 154247079 | 6241 |
| Ryan | 154247083 | 6249 |
| Ryan | 154247084 | 6251 |
+-------+-----------+----------+
我想根据d
和a
中的值添加列c
(请参阅下面的预期表格)。 a
中的值是主题的名称,b
是其属性之一,c
是另一个属性。因此,如果每个主题的c
值彼此相差15个单位,则为它们分配相同的群集编号(例如,c
中Ryan
的每个值都在15个单位内,所以它们都被分配1),但是如果没有为它们分配不同的值John
,其中每一行获得d
的不同值。
+-------+-----------+----------+---+
|a | b | c |d |
+-------+-----------+----------+---+
| John | 225630096 | 447 | 1 |
| John | 225630118 | 491 | 2 |
| John | 225630206 | 667 | 3 |
| John | 225630480 | 1215 | 4 |
| John | 225630677 | 1609 | 5 |
| John | 225631010 | 2275 | 6 |
| Ryan | 154247076 | 6235 | 1 |
| Ryan | 154247079 | 6241 | 1 |
| Ryan | 154247083 | 6249 | 1 |
| Ryan | 154247084 | 6251 | 1 |
+-------+-----------+----------+---+
我不确定这是否可以在mysql中完成,但如果没有,我也欢迎任何基于python的答案,在这种情况下,以cdv格式处理此表。
感谢。
答案 0 :(得分:0)
您可以使用带变量的查询:
SELECT a, b, c,
CASE WHEN @last_a != a THEN @d:=1
WHEN (@last_a = a) AND (c>@last_c+15) THEN @d:=@d+1
ELSE @d END d,
@last_a := a,
@last_c := c
FROM
tablename, (SELECT @d:=1, @last_a:=null, @last_c:=null) _n
ORDER BY a, c
请参阅小提琴here。
<强>解释强>
我正在使用tablename
和子查询(SELECT ...) _n
之间的连接来初始化一些变量(d初始化为1,@ pop_a为null,@ last_c为null)。
然后,对于每一行,我正在检查最后遇到的 - 前一行中的那一行 - 是否与当前的a不同:在这种情况下将@d设置为1(并返回它)。
如果最后遇到a与当前行相同且c大于最后遇到的c + 15,则增加@d并返回其值。
否则,只返回d而不增加它。当a没有改变且c不大于前一个c + 15时会发生这种情况,或者这将发生在第一行(因为@last_a和@last_c已被初始化为null)。
为了使其有效,我们需要通过a和c来订购。