SQL выбирает максимальную дату, которая меньше определенной даты - PullRequest
0 голосов
/ 04 сентября 2018

Я пытаюсь сделать запрос в Access, который выбирает максимальную дату из таблицы, которая меньше, чем дата конкретной другой записи в таблице, и я должен проверить, существует ли эта запись.

Я знаю, что описание немного сбивает с толку, поэтому я попытаюсь объяснить его в псевдокоде:

If(Record exists where editing_type = "Notranja kontrola")
   SELECT MAX(created_at) that is smaller than ( MIN(created_at) Where 
   editing_type = "Notranja kontrola") 
   WHERE editing_type = "Zajem"

Если запись с edit_type = "Notranja kontrola" не существует, Я не хочу выбирать дату. Я хочу вернуть NULL. Если это так, я хочу выбрать максимальную дату, где edit_type = "Zajem", то есть меньше, чем MIN (дата), ГДЕ edit_type = "Notranja kontrola")

Запрос, который я предложил:

SELECT 
spr.ob_id AS Obcina, 
spr.ko, 
'DA' AS Dodeljeno,
(   
SELECT MAX(created_at)
FROM ( 
    SELECT created_at
    FROM spremljanje_uporabnik_zajem
    WHERE created_at < (
        SELECT MIN(created_at)
        FROM spremljanje_uporabnik_zajem
        WHERE editing_type = "Notranja kontrola" AND ko = spr.ko AND VAL(ko) BETWEEN  0 AND 9999
        )
    )   
WHERE editing_type = "zajem" AND ko = spr.ko AND VAL(ko) BETWEEN  0 AND 9999
    AND EXISTS (
        SELECT 1
        FROM spremljanje_uporabnik_zajem
        WHERE editing_type = "Notranja kontrola" AND ko = spr.ko AND VAL(ko) BETWEEN  0 AND 9999
    )
) AS [krneki],

(SELECT
.....


)

FROM spremljanje_uporabnik_zajem AS spr

WHERE VAL(ko) BETWEEN  0 AND 9999

GROUP BY spr.ob_id, spr.ko

ORDER BY Val(spr.ko);

часть WHERE VAL(ko) BETWEEN 0 AND 9999 предназначена только для проверки правильности записи.

Когда я пытаюсь выполнить запрос, я получаю приглашение ввести spr.ko вместо того, чтобы принимать его как значение из внешнего запроса. Как мне это исправить?

Внешний запрос существует, потому что мне нужно выбрать и другие вещи.

РЕДАКТИРОВАТЬ + РЕДАКТИРОВАТЬ2: Я только выбираю из таблицы "spremlanje_uporabniki_zajem"

Пример данных (spremlanje_uporabniki_zajem):

    ob_id   ko     editing_type        created_at
    40      100       zajem             1.01.2018
    40      100       zajem             2.01.2018
    40      100  notranja kontrola      3.01.2018
    40      100       zajem             4.01.2018
    90      550       zajem             2.01.2018
    40      100       zajem             6.01.2018
    40      20        zajem             7.01.2018
    40      20        zajem             8.01.2018
    40      20   notranja kontrola      9.01.2018
    40      20        zajem            10.01.2018
    40      100       zajem            11.01.2018
    40      20        zajem            12.01.2018
    40      20  notranja kontrola      13.01.2018
    40     100  notranja kontrola      13.01.2018


Expected REXPECTED RESULT:      


    ob_id    ko   Dodeljeno     krneki
      40    100      DA       2.01.2018
      90    550      DA          NULL
      40    20       DA       8.01.2018

Спасибо

Ответы [ 4 ]

0 голосов
/ 05 сентября 2018

Решение, на случай, если кому-то интересно (изменено после публикации @Juan Carlos Oropeza - замена CTE подзапросом и использование синтаксиса MS Access)

SELECT 
    t.ob_id, 
    t.ko, 
    MAX(iif(c.min_kontrola IS NOT NULL,t.created_at)) as krneki,

FROM spremljanje_uporabnik_zajem t

LEFT JOIN 
    (
    SELECT  ob_id, ko, MIN(created_at) AS min_kontrola
    FROM spremljanje_uporabnik_zajem 
    WHERE editing_type = 'notranja kontrola'
    GROUP BY ob_id, ko
    )AS c

ON (t.ob_id = c.ob_id
AND t.ko = c.ko
AND (t.created_at < c.min_kontrola)
AND VAL(t.ko) BETWEEN 0 AND 9999
AND t.editing_type = "zajem"
)
GROUP BY t.ob_id, t.ko 
ORDER BY  t.ob_id, t.ko;
0 голосов
/ 04 сентября 2018
  • Сначала вам нужно вычислить MIN(date) для каждой группы
  • Затем вы выполняете LEFT JOIN, чтобы получить строки с датой, предшествующей найденной MIN(date)
  • Теперь вы группируете все эти строки вместе
  • Используя условное MAX(CASE), вы удаляете дату с нулевыми значениями.

SQL DEMO

WITH cte as (
      SELECT  "ob_id", "ko", MIN("created_at") min_kontrola
      FROM Table1 
      WHERE "editing_type" = 'notranja kontrola'
      GROUP BY "ob_id", "ko"
)  
SELECT t."ob_id", 
       t."ko", 
       MAX(CASE WHEN c.min_kontrola IS NOT NULL 
                THEN t."created_at"
           END) as krneki
FROM Table1 t 
LEFT JOIN cte c
  ON t."ob_id" = c."ob_id"
 AND t."ko" = c."ko"
 AND t."created_at" < c.min_kontrola
GROUP BY t."ob_id", t."ko" 
ORDER BY  t."ob_id", t."ko";

OUTPUT

| ob_id |  ko |        max |
|-------|-----|------------|
|    40 |  20 | 2018-01-08 |
|    40 | 100 | 2018-01-02 |
|    90 | 550 |     (null) |

В SQL DEMO у вас есть два запроса. Второй я удаляю GROUP BY, чтобы вы могли видеть результат перед последними шагами.

0 голосов
/ 05 сентября 2018

После понимания «требования NULL» мне пришлось пересмотреть мой ответ. Ваш запрос был не так уж плох, но я нашел некоторые вещи, которые можно улучшить / исправить:

  • «Предложение zajem WHERE» должно быть не предложением WHERE, а дополнительным критерием для предложения WHERE на следующем внутреннем уровне.
  • «Критерий EXISTS» может быть удален, потому что, когда нет записи, также не существует MIN, и поэтому сравнение с любой «записью zajem» не удастся, что приведет к «не максимуму» ( NULL) по желанию.
  • Нет необходимости в «подзапросе zajem», критерии можно применять непосредственно в «MAX-запросе».

Что из этого получилось:

SELECT 
    spr.ob_id AS Obcina
  , spr.ko
  , 'DA' AS Dodeljeno
  , (   
        SELECT MAX(created_at)
        FROM spremljanje_uporabnik_zajem
        WHERE editing_type = "zajem" AND ko = spr.ko AND VAL(ko) BETWEEN  0 AND 9999
          AND created_at < (
            SELECT MIN(created_at)
            FROM spremljanje_uporabnik_zajem
            WHERE editing_type = "Notranja kontrola" AND ko = spr.ko AND VAL(ko) BETWEEN  0 AND 9999
            )
    ) AS [krneki]
FROM spremljanje_uporabnik_zajem AS spr
WHERE VAL(ko) BETWEEN  0 AND 9999
GROUP BY spr.ob_id, spr.ko
ORDER BY VAL(spr.ko);

И Access может запустить его без всяких проблем:

query result

0 голосов
/ 04 сентября 2018

может быть, вы можете взять этот запрос и завершить остальное самостоятельно.

select
  t3.ob_id,
  t3.ko,
  t4.max_created_at
from(
select distinct
  ob_id,
  ko
from dummyTable
) t3
left join (
SELECT
  t1.ob_id,
  t1.ko,
  max(t1.created_at) max_created_at
from dummyTable t1
where exists (
  select
    1
  from dummyTable t2
  where t2.ob_id = t1.ob_id and
  t2.ko = t1.ko and
  t2.editing_type = 'nontranja kontrola' and
  t1.created_at < t2.created_at
)) t4
on t4.ob_id = t3.ob_id and
t4.ko = t3.ko

Вы можете попробовать здесь .

...