5

次の表があるとします。

ID州の日付
12 1 2009-07-16 10:00
45    2       2009-07-16 13:00
67    2       2009-07-16 14:40
77 1 2009-07-16 15:00
89 1 2009-07-16 15:30
99 1 2009-07-16 16:00

質問:
状態の変化の間の境界を維持しながら、フィールド「状態」でグループ化するにはどうすればよいですか?

SELECT MIN(ID) AS ID, State, MIN(Date) AS Date, COUNT(ID) AS Count
FROM table GROUP BY State

結果は次のようになります。

ID州の日付数
12 1 2009-07-16 10:00 4
45 2 2009-07-16 13:00 2

しかし、これは望ましい出力です。

ID州の日付数
12 1 2009-07-16 10:00 1
45 2 2009-07-16 13:00 2
77 1 2009-07-16 15:00 3

これはSQLで可能ですか?私は今のところ解決策を見つけられませんでした...
4

4 に答える 4

10
SELECT  MIN(id) AS id, MIN(ts) AS ts, MIN(state) AS state, COUNT(*) cnt
FROM    (
        SELECT  @r := @r + (@state != state) AS gn,
                @state := state AS sn,
                s.*
        FROM    (
                SELECT  @r := 0,
                        @state := 0
                ) vars,
                t_state s
        ORDER BY
                ts
        ) q
GROUP BY
        gn

テスト用のテーブル作成スクリプト:

CREATE TABLE t_state (id INT NOT NULL PRIMARY KEY, state INT NOT NULL, ts DATETIME NOT NULL);

INSERT
INTO  t_state
VALUES
(12,   1,      '2009-07-16 10:00'),
(45,   2,      '2009-07-16 13:00'),
(67,   2,      '2009-07-16 14:40'),
(77,   1,      '2009-07-16 15:00'),
(89,   1,      '2009-07-16 15:30'),
(99,   1,      '2009-07-16 16:00');
于 2009-07-16T10:19:24.937 に答える
2

これは、MSSQLサーバーでCTEを使用して行う方法です

-- DROP TABLE MyLog
CREATE TABLE MyLog(
        ID          INT PRIMARY KEY
        , State     INT
        , Date      DATETIME
        )
INSERT MyLog
SELECT 12, 1, '2009-07-16 10:00' UNION ALL
SELECT 45, 2, '2009-07-16 13:00' UNION ALL
SELECT 67, 2, '2009-07-16 14:40' UNION ALL
SELECT 77, 1, '2009-07-16 15:00' UNION ALL
SELECT 89, 1, '2009-07-16 15:30' UNION ALL
SELECT 99, 1, '2009-07-16 16:00'

;WITH   CTE
AS      (
        SELECT  ROW_NUMBER() OVER(ORDER BY ID) AS RowNo
                , *
        FROM    MyLog
        )
, MyLogGroup
AS      (
        SELECT  l.*
                , ( SELECT  MAX(ID)
                    FROM    CTE c
                    WHERE   NOT EXISTS (SELECT * FROM CTE
                                        WHERE RowNo = c.RowNo-1 AND State = c.State)
                            AND c.ID <= l.ID) AS GroupID
        FROM    MyLog l
        )
SELECT  *
FROM    MyLogGroup
于 2009-07-16T10:48:25.830 に答える
1

以下は、Quassnoi が提供するようなソリューションがどのように機能するかについてのより長い説明です。

于 2012-01-18T22:16:55.100 に答える
0

ここで明白なことを述べているかもしれませんが、Transact-SQL を使用する意思がある場合は、テーブルの行を反復処理して独自の結果セットを構築できます。これはおそらく面倒に思えますが、間違いなく機能します。 . 反復は、カーソルを使用せずに実行できます。

于 2009-07-16T10:21:30.533 に答える