MySQL如何查询某列的修改次数
Posted
技术标签:
【中文标题】MySQL如何查询某列的修改次数【英文标题】:How to query number of changes in a column in MySQL 【发布时间】:2012-08-24 20:08:21 【问题描述】:我有一个存储具有两个属性的项目的表。所以表格有三列:
item_id | property_1 | property_2 | insert_time
1 | 10 | 100 | 2012-08-24 00:00:01
1 | 11 | 100 | 2012-08-24 00:00:02
1 | 11 | 101 | 2012-08-24 00:00:03
2 | 20 | 200 | 2012-08-24 00:00:04
2 | 20 | 201 | 2012-08-24 00:00:05
2 | 20 | 200 | 2012-08-24 00:00:06
也就是说,每次任何项目的 either 属性发生变化时,都会插入一个新行。还有一列存储插入时间。现在我想获取property_2
中的更改次数。对于上表,我应该得到
item_id | changes_in_property_2
1 | 2
2 | 3
我怎样才能得到这个?
【问题讨论】:
你的表上是否有 id 列,或者每条记录都有一个 datetime 字段?只是好奇,否则有没有办法对记录进行排序? 鉴于示例数据中的第 4 行和第 6 行之间没有区别,您将无法确定更改。您可能需要添加某种可排序的时间信息,以便按顺序比较前一个值和下一个值。 由于第 4 行和第 6 行是相同的,因此确定更改将是非常困难。您需要另一列或不同的记录方法。 @Tom,@ahillman3,@njk 我确实有一列插入时间。我刚刚编辑了我的问题。 @seanhawk 你桌上的钥匙是什么? 【参考方案1】:这将告诉您输入了多少不同的值。但是,如果将其更改回以前的值,则不会将其视为新更改。如果没有数据的年表,很难做更多的事情。
select item_id, count(distinct property_2)
from Table1
group by item_id
【讨论】:
我确实有一列插入时间。我刚刚编辑了我的问题。【参考方案2】:这是最接近您想要的结果的方法。但是我应该注意,您是在询问基于item_id
对property_2
的更改次数。如果您正在严格分析这两列,那么item_id
1 只有 1 处更改,item_id
2 有 2 处更改。您需要将结果扩展为由 property_1
聚合。希望这个fiddle 能告诉你原因。
SELECT a.item_id,
SUM(
CASE
WHEN a.property_2 <>
(SELECT property_2 FROM tbl b
WHERE b.item_id = a.item_id AND b.insert_time > a.insert_time LIMIT 1) THEN 1
ELSE 0
END) AS changes_in_property_2
FROM tbl a
GROUP BY a.item_id
【讨论】:
【参考方案3】:我的看法:
SELECT
i.item_id,
SUM(CASE WHEN i.property_1 != p.property_1 THEN 1 ELSE 0 END) + 1
AS changes_1,
SUM(CASE WHEN i.property_2 != p.property_2 THEN 1 ELSE 0 END) + 1
AS changes_2
FROM items i
LEFT JOIN items p
ON p.time =
(SELECT MAX(q.insert_time) FROM items q
WHERE q.insert_time < i.insert_time AND i.item_id = q.item_id)
GROUP BY i.item_id;
i
中未选择的每个项目都有一个条目,该条目没有前任。不过,这很重要,这就是总和增加的原因。
【讨论】:
@Animep.time
指的是什么?如果item_id
没有变化怎么办?好像没有变化你也会加1。
我知道,这令人困惑,但如果您仔细查看 OP 给出的数字,项目的每个第一个条目本身都被视为更改。如您所见,即使从100
到101
只有一次飞跃,他也希望对 (item_1
, property_2
) 进行 2 次更改。对于i
中的每个条目,p.time
指的是同一项目的前一个条目的 insert_time。因此,由于我们使用的是内连接,因此不会出现没有前任的条目,因此我们必须手动将它们添加到总和中(并且我们知道每个条目总是正好为 1)。
我刚刚注意到最好使用LEFT JOIN
,以防一个项目只有一个条目。它不会弄乱总和,因为没有前任的条目将具有 p.property_1
和 p.property_2
到 NULL
,这会导致 CASE ... WHEN
构造返回 0。【参考方案4】:
我会这样做,使用用户定义的变量来跟踪前一行的值。
SELECT item_id, MAX(c) AS changes_in_property_2
FROM (
SELECT IF(@i = item_id, IF(@p = property_2, @c, @c:=@c+1), @c:=1) AS c,
(@i:=item_id) AS item_id,
(@p:=property_2)
FROM `no_one_names_their_table_in_sql_questions` AS t,
(SELECT @i:=0, @p:=0) AS _init
ORDER BY insert_time
) AS sub
GROUP BY item_id;
【讨论】:
以上是关于MySQL如何查询某列的修改次数的主要内容,如果未能解决你的问题,请参考以下文章