4

1つのSQLクエリで1つの列の最新の値の変更の日付を取得するにはどうすればよいですか?

考えられるデータベースの状況:

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
4

7 に答える 7

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 ; 

SQLでテスト済み-Fiddle


そして、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 ;
于 2012-12-04T15:23:11.307 に答える
0

これを試して ::

Select 
    MAX(`Date`), state from mytable 

    group by state
于 2012-12-04T14:07:55.230 に答える
0

別の列「changed datetime」を追加すると、NOW() を挿入する更新トリガーを使用してこれを埋めることができます。変更された列でテーブルの順序をクエリすると、最初になります。

CREATE TRIGGER `trigger` BEFORE UPDATE ON `table` 
FOR EACH ROW
BEGIN
SET ROW.changed = NOW();
END$$
于 2012-12-04T14:04:52.390 に答える
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

基本的に、これは、後の値に対して状態の変化が見つからないことを初めて要求します。このクエリは、大規模なデータ セットに対してひどくスケーリングする可能性があることに注意してください....

于 2012-12-04T14:39:31.717 に答える
0

これが答えだと思います:

SELECT 
    DISTINCT State AS State, `Date`
FROM 
    Table_1 t1
WHERE t1.`Date`=(SELECT MAX(`Date`) FROM Table_1 WHERE State=t1.State)

...そしてテスト:

http://sqlfiddle.com/#!2/8b0d8/5

于 2012-12-04T14:15:04.800 に答える
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 列の前の値を取得し、外側の選択では、現在の状態値とは異なるラグ値を持つ変更の日付をマークします。外では、変更の日付から最新の日付を取得しています...これがあなたが必要としていたものであることを願っています.

于 2014-01-31T19:31:30.853 に答える
-1
SELECT MAX(DATE) FROM YOUR_TABLE

上記の回答は、OP のニーズを満たしていないようです。

AFTER INSERT/UPDATE TRIGGERによる更新された回答

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これが:D だったらいいのにと思いintegerます。両方の列で 2 つの最大サブクエリを結合すると、簡単に解決できます。それでも、文字列操作の正規表現は、状態列の最大値を見つけることができます。最後に、このアプローチにはlimit x. しかし、まだロープ穴があります。とにかく、あなたの必要性を理解するのに時間がかかりました:$

于 2012-12-04T14:04:33.027 に答える