像FULL OUTER JOIN之类的东西,但只有第一次匹配

时间:2016-07-07 15:54:34

标签: sql join mariadb

我正在开发MariaDB 10.1.12。

首先让我们看一下" prod_line_state" :

   id   |      timestamp      | state
---------------------------------------
 CHxxx  | 2000-01-01 00:00:00 |   0
 CHxxx  | 2016-07-07 16:18:49 |   1
 CHxxx  | 2016-07-07 16:19:00 |   0
 CHyyy  | 2000-01-01 00:00:00 |   0
 CHyyy  | 2016-07-07 16:28:08 |   0
 CHyyy  | 2016-07-07 16:29:23 |   1
 CHyyy  | 2016-07-07 16:29:28 |   0
 CHyyy  | 2016-07-07 16:29:32 |   1
 CHyyy  | 2016-07-07 16:29:39 |   0
 CHyyy  | 2016-07-07 17:22:55 |   1

我想要这个:

   id   |      StartedAt      |      StoppedAt      
---------------------------------------
 CHxxx  | 2000-01-01 00:00:00  | 2000-01-01 00:00:00
 CHxxx  | 2016-07-07 16:18:49  | 2016-07-07 16:19:00
 CHyyy  | 2000-01-01 00:00:00  | 2000-01-01 00:00:00
 CHyyy  | 2000-01-01 00:00:00  | 2016-07-07 16:28:08
 CHyyy  | 2016-07-07 16:29:23  | 2016-07-07 16:29:28
 CHyyy  | 2016-07-07 16:29:32  | 2016-07-07 16:29:39
 CHyyy  | 2016-07-07 17:22:55  | 3000-01-01 00:00:00

" 2000-01-01 00:00:00"和" 3000-01-01 00:00:00"是假日期。这意味着,没有开始记录或没有停止记录。

为此,我做了以下查询,女巫很丑,但我不知道如何做得更好:

SELECT id, Timestamp as StartedAt, IFNULL((SELECT Timestamp
                                           FROM prod_line_state
                                           WHERE State = 0 AND started.id = prod_line_state.id AND prod_line_state.Timestamp > started.Timestamp
                                           ORDER BY Timestamp ASC
                                           LIMIT 1), '3000-1-1 00:00:00') as StoppedAt
FROM prod_line_state started
WHERE State <> 0
UNION
SELECT id, IFNULL((SELECT Timestamp
                   FROM prod_line_state
                   WHERE State <> 0 AND stopped.id = prod_line_state.id AND prod_line_state.Timestamp < stopped.Timestamp
                   ORDER BY Timestamp DESC
                   LIMIT 1), '2000-1-1 00:00:00') as StartedAt, Timestamp as StoppedAt
FROM prod_line_state stopped
WHERE State = 0
ORDER BY id, startedAt, stoppedAt

所以我搜索更好的方法来做到这一点。有什么想法吗?

3 个答案:

答案 0 :(得分:0)

SELECT id,
       IF(state = 0, MAX(timestamp), NULL) AS StartedAt,
       IF(state = 1, MAX(timestamp), NULL) AS StoppedAt
    FROM ( SELECT
                @seq := @seq + IF(id != @prev_id OR state = 0, 1, 0) AS seq,
                id, state, timestamp,
                @prev_id := id AS junk
            FROM ( SELECT @prev_id := '', @seq := 0 ) AS init
            JOIN prod_line_state
            ORDER BY id, timestamp
         ) AS a
    GROUP BY  seq
    ORDER BY  seq

如果结果不合适,请为您的测试用例提供CREATE TABLEINSERTs

答案 1 :(得分:0)

你的结果:

session.createCriteria(KwPaymentLinkMastertest.class).add(Restrictions.eq("requestId", Integer.parseInt(transactionReferenceNumber) )).uniqueResult();


   KwPaymentImagetest image = (KwPaymentImagetest) session.createCriteria(KwPaymentImagetest.class).add(Restrictions.eq("kwPaymentLinkMastertest", kwPaymentLinkMastertest)).uniqueResult();

我想要的结果:

  id  |      StartedAt      | StoppedAt 
--------------------------------------- 
CHxxx | 2016-07-07 16:18:49 |   NULL 
CHxxx | 2016-07-07 16:19:00 |   NULL 
CHyyy | 2000-01-01 00:00:00 |   NULL 
CHyyy | 2016-07-07 16:29:23 |   NULL 
CHyyy | 2016-07-07 16:29:32 |   NULL 
CHyyy | 2016-07-07 17:22:55 |   NULL

答案 2 :(得分:0)

对不起,

以下是子查询结果:

 seq | prodLine | state |      timestamp      | junk
-----------------------------------------------------
  1  |  CHxxx   |   0   | 2000-01-01 00:00:00 | CHxxx
  1  |  CHxxx   |   1   | 2016-07-07 16:18:49 | CHxxx
  2  |  CHxxx   |   0   | 2016-07-07 16:19:00 | CHxxx
  3  |  CHyyy   |   0   | 2000-01-01 00:00:00 | CHyyy
  4  |  CHyyy   |   0   | 2016-07-07 16:28:08 | CHyyy
  4  |  CHyyy   |   1   | 2016-07-07 16:29:23 | CHyyy
  5  |  CHyyy   |   0   | 2016-07-07 16:29:28 | CHyyy
  5  |  CHyyy   |   1   | 2016-07-07 16:29:32 | CHyyy
  6  |  CHyyy   |   0   | 2016-07-07 16:29:39 | CHyyy
  6  |  CHyyy   |   1   | 2016-07-07 17:22:55 | CHyyy