如何使用一个SQL查询在一列中获取最新值更改的日期?
可能的数据库情况:
Date State
2012-11-25 state one
2012-11-26 state one
2012-11-27 state two
2012-11-28 state two
2012-11-29 state one
2012-11-30 state one
因此结果应该以2012-11-29作为最新变化状态返回。如果我按状态值分组,我将在数据库中第一次获得该状态的日期。
查询将对表进行分组并显示状态,并在日期字段中创建该状态的最新日期。
根据给定的输入,输出将是
Date State
2012-11-30 state one
2012-11-28 state two
答案 0 :(得分:2)
这将使你获得最后一个状态:
-- Query 1
SELECT state
FROM tableX
ORDER BY date DESC
LIMIT 1 ;
封装上述内容,我们可以使用它来获取最后一次更改之前的日期:
-- Query 2
SELECT t.date
FROM tableX AS t
JOIN
( SELECT state
FROM tableX
ORDER BY date DESC
LIMIT 1
) AS last
ON last.state <> t.state
ORDER BY t.date DESC
LIMIT 1 ;
然后使用它来查找最后一次更改发生的日期(或整行):
-- Query 3
SELECT a.date -- can also be used: a.*
FROM tableX AS a
JOIN
( SELECT t.date
FROM tableX AS t
JOIN
( SELECT state
FROM tableX
ORDER BY date DESC
LIMIT 1
) AS last
ON last.state <> t.state
ORDER BY t.date DESC
LIMIT 1
) AS b
ON a.date > b.date
ORDER BY a.date
LIMIT 1 ;
中进行测试
使用MySQL变量的解决方案:
-- Query 4
SELECT date
FROM
( SELECT t.date
, @r := (@s <> state) AS result
, @s := state AS prev_state
FROM tableX AS t
CROSS JOIN
( SELECT @r := 0, @s := ''
) AS dummy
ORDER BY t.date ASC
) AS tmp
WHERE result = 1
ORDER BY date DESC
LIMIT 1 ;
答案 1 :(得分:0)
SELECT MAX(DATE) FROM YOUR_TABLE
以上答案似乎并不能满足OP的需要。
插入/更新触发后更新的答案
DELCARE @latestState varchar;
DELCARE @latestDate date;
CREATE TRIGGER latestInsertTrigger AFTER INSERT ON myTable
FOR EACH ROW
BEGIN
IF OLD.DATE <> NEW.date THEN
SET @latestState = NEW.state
SET @latestDate = NEW.date
END IF
END
;
CREATE TRIGGER latestUpdateTrigger AFTER UPDATE ON myTable
FOR EACH ROW
BEGIN
IF OLD.DATE = NEW.date AND OLD.STATE <> NEW.STATE THEN
SET @latestState = NEW.state
SET @latestDate = NEW.date
END IF
END
;
您可以使用以下查询来添加/更新最新记录:
SELECT DATE, STATE FROM myTable
WHERE STATE = @latestState
OR DATE = @latestDate
ORDER BY DATE DESC
;
结果:
DATE STATE
November, 30 2012 00:00:00+0000 state one
November, 28 2012 00:00:00+0000 state two
November, 27 2012 00:00:00+0000 state two
以上查询结果需要根据您的需要限制为2,3或n。
坦率地说,您似乎希望根据您提供的数据样本从两列获得最大值。假设您的州只随日期增加。只有我希望state
是integer
:D
然后在两列上联合两个最大子查询就可以轻松解决它。仍然是字符串操作正则表达式可以找到状态列中的最大值。最后,这种方法需要limit x
。但它仍然有 lope hole 。 无论如何,我花了一些时间来解决你的需求:$
答案 2 :(得分:0)
如果您添加另一列'更改日期时间',则可以使用插入NOW()的更新触发器来填充此列。如果您在更改的列上查询表顺序,它将首先结束。
CREATE TRIGGER `trigger` BEFORE UPDATE ON `table`
FOR EACH ROW
BEGIN
SET ROW.changed = NOW();
END$$
答案 3 :(得分:0)
试试这个::
Select
MAX(`Date`), state from mytable
group by state
答案 4 :(得分:0)
我相信这就是答案:
SELECT
DISTINCT State AS State, `Date`
FROM
Table_1 t1
WHERE t1.`Date`=(SELECT MAX(`Date`) FROM Table_1 WHERE State=t1.State)
......和测试:
答案 5 :(得分:0)
如果你一直在使用postgres,你可以使用“LEAD .. OVER”来比较同一个表中的不同行。我还没有在mysql中找到相同的功能。
有点毛茸茸,但我想这会做:
select min(t1.date) from table_1 t1 where
(select count(distinct state) from table_1 where table_1.date>=t1.date)=1
基本上,这要求第一次没有找到任何后续值的状态变化。请注意,这个查询可能会对大型数据集造成严重影响....
答案 6 :(得分:0)
我认为你最好的选择是分析功能。试试这个 - 性能应该是好的:
SELECT *
FROM test
WHERE my_date = (SELECT MAX (my_date)
FROM (SELECT MY_DATE
FROM ( SELECT MY_DATE,
STATE,
LAG (state) OVER (ORDER BY MY_DATE)
lag_val
FROM test
ORDER BY MY_DATE) a
WHERE state != lag_val))
在内部选择中,LAG函数获取STATE列中的先前值,而外部选择I中标记更改日期 - 滞后值不同于当前状态值的那些。在外面,我将从变更日期开始获取最新日期...我希望这就是您所需要的。