Как сделать несколько проверок для значения в MySQL - PullRequest
0 голосов
/ 19 апреля 2019

Вот мой стол

enter image description here

Предположения:

.. Если последняя действительная запись для идентификатора равна 1, то это хорошо

.. Если последняя запись действительного значения для идентификатора равна 0, то это означает, что нужно проверить предыдущую запись, где значение действительное равно 1

.

.. Если последняя запись действительного значения для идентификатора равна нулю, то это бесполезно

Теперь я пытаюсь сделать

  1. Получить те идентификаторы, где последняя запись для этого идентификатора получила 1 в качестве действительного значения

  2. Если действительное значение последней записи для идентификатора равно 0, то оно будет принимать запись до того, где действительное значение равно 1.

  3. Если значение 'valid' последней записи для идентификатора равно 0, но значение выше нуля, то этот идентификатор полностью исключается в результате

Нет, это результат, который я пытаюсь достичь

enter image description here

Так как это сделать.

Как написать sql для этого.

Заранее спасибо.

Ответы [ 2 ]

0 голосов
/ 19 апреля 2019

Будущая версия MySQL будет иметь боковое соединение

Здесь будущее. Будущее уже здесь, я запускаю запрос ниже на MySQLWorkbench с MySQLверсия 8.0.15, боковое соединение работает.

Живой тест для Postgres.MySQL 8.0.15 пока недоступен на db-fiddle.com, только его версия 8.0.12.

Живой тест: https://www.db -fiddle.com / f / jQwSuyJ8Vwr3inaty6XVk7 / 1

with lr as -- gets last row of each id
(
    select  tbl.*
    from (select id, max(no) as max_no from tbl group by id) as ln 
    join tbl on (ln.id,ln.max_no) = (tbl.id,tbl.no) 
)
select x.*
from lr
cross join lateral
(
    select tbl.*
    from tbl 
    where
        -- valid = 1, good:
        lr.valid = 1 and tbl.no = lr.no

        -- valid = 0, check the one before it:
        or lr.valid = 0 and tbl.id = lr.id and tbl.no < lr.no

        -- optional. since it doesn't match anything here, no rows matched:
        --     or lr.valid is null and 1 = 0            
    order by tbl.no desc
    limit 1
) as x
where x.valid is not null
order by x.id;

Вывод:

| no  | id  | valid |
| --- | --- | ----- |
| 1   | 1   | 1     |
| 5   | 2   | 1     |
| 10  | 4   | 1     |
| 16  | 6   | 1     |

MySQL 8.0.15 доступен на dbfiddle.uk: https://dbfiddle.uk/?rdbms=mysql_8.0&fiddle=95a873135d22bcfce3e59839d283e9a0

Postgres можно сделать короче, используя DISTINCT ON вместо соединения с макс (нет):

Тест в реальном времени: https://www.db -fiddle.com / f / jQwSuyJ8Vwr3inaty6XVk7 / 2

with lr as -- gets last row of each id
(
    select distinct on (id) 
        *
    from tbl
    order by id, no desc
)
0 голосов
/ 19 апреля 2019

Я думаю, что вы можете справиться с этим методом грубой силы. То есть получить информацию no и valid из двух последних строк и использовать ее в предложении where:

select id, no, valid
from (select t.*,
             (select t2.no
              from t t2
              where t2.id = t.id
              order by t2.no desc
              limit 1
             ) as last_no,
             (select t2.valid
              from t t2
              where t2.id = t.id
              order by t2.no desc
              limit 1
             ) as last_valid,
             (select t2.no
              from t t2
              where t2.id = t.id
              order by t2.no desc
              limit 1, 1
             ) as last_no_2,    
             (select t2.valid
              from t t2
              where t2.id = t.id
              order by t2.no desc
              limit 1, 1
             ) as last_valid_2      
      from t
     ) t
where (last_valid = 1 and no = last_no) or
      (last_valid = 0 and last_valid_2 = 1 and no = last_no_2)
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...