Более одной строки, возвращенной подзапросом и справкой по формулировке логики c - PullRequest
1 голос
/ 18 апреля 2020

У меня есть 3 таблицы: event table, down_event table, dummy table

В event table содержится столбец terminal_id, event_start_adj, event_end_adj и event_duration_sec см. картинка ниже: event table

Теперь в down_event table он содержит столбец id, terminal_id, event_description, down_date, down_time, down_duration_sec. См. Рисунок ниже:

down_event table

Наконец, третья таблица - это dummy table, которая содержит столбцы: terminal_id, availability_date, availability_time duration_sec. См. Рисунок ниже:

dummy table

В dummy table duration_sec имеет значение по умолчанию 3600 , тогда как availability_time интервалы от 00: 00: 00 до 23: 00: 00 . availability_date - это та, которая сортирует всю дату, когда событие произошло в таблице down_event.

Проблема в том, что мне нужно вычесть down_duration_sec из значения по умолчанию duration_sec dummy table и обновить это. Так, если down_duration_sec, например, равно 1 секунде, то это будет 3600 - 1 = 3599. Тогда, если это событие произошло в 03: 04: 44 (находится в event table и down_event table) он упадет на 03: 00: 00 на пустом столе. Затем event_duration_mins, который находится на event table со значением 42 , будет добавлен в 03: 00: 00 , обновив его в dummy table до 03: 42: 00 и duration_se c до 3599 для даты 2020-04-01 .

Сначала я попытался обновить duration_se c с помощью мой запрос ниже:

UPDATE dashboard.dummy SET duration_sec = 3600 - (SELECT down_duration_sec FROM dashboard.down_event WHERE terminal_id IN (SELECT terminal_id FROM dashboard.dummy)) WHERE terminal_id IN (SELECT terminal_id FROM dashboard.down_event WHERE terminal_id IN (SELECT terminal_id FROM dashboard.dummy)) AND availability_date IN (SELECT down_date FROM dashboard.down_event WHERE down_date IN (SELECT availability_date FROM dashboard.dummy))

, но проблема PostgreSQL вызвала ошибку ОШИБКА: более одной строки, возвращенной подзапросом, использованным в качестве выражения . Мне нужна помощь по моему запросу и что делать с другими столбцами в моей таблице dummy, поэтому я все объяснил. Я планирую обновить его один за другим, но я думаю, что это займет много времени. Поэтому, если есть какая-то идея, которую я могу попробовать, я попробую, но сейчас я не знаю, почему PostgreSQL выдаёт мне эту ошибку. Я из-за знака = в duration_se c = , но я пытался сделать это как IN , но все равно не будет работать.

Редактировать:

Каждый terminal_id имеет разные down_duration_se c на down_event_table.

Пожалуйста, смотрите скриншот ниже: duration-sec

1 Ответ

1 голос
/ 18 апреля 2020

Ваш подзапрос возвращает больше строки, поэтому вы можете попытаться использовать ограничение 1

UPDATE dashboard.dummy 
SET duration_sec = 3600 - (
    SELECT down_duration_sec 
    FROM dashboard.down_event 
    WHERE terminal_id IN (SELECT terminal_id FROM dashboard.dummy)
    LIMIT 1
) 
WHERE terminal_id IN (  
    SELECT terminal_id 
    FROM dashboard.down_event 
    WHERE terminal_id IN (SELECT terminal_id FROM dashboard.dummy)
) 
AND availability_date IN (
    SELECT down_date 
    FROM dashboard.down_event 
    WHERE down_date IN ( SELECT availability_date FROM dashboard.dummy)
)

ИЛИ использовать функцию агрегации, например: min () или max () o avg ()

UPDATE dashboard.dummy 
SET duration_sec = 3600 - (
    SELECT min(down_duration_sec) 
    FROM dashboard.down_event 
    WHERE terminal_id IN (SELECT terminal_id FROM dashboard.dummy)
) 
WHERE terminal_id IN (  
    SELECT terminal_id 
    FROM dashboard.down_event 
    WHERE terminal_id IN (SELECT terminal_id FROM dashboard.dummy)
) 
AND availability_date IN (
    SELECT down_date 
    FROM dashboard.down_event 
    WHERE down_date IN ( SELECT availability_date FROM dashboard.dummy)
)

Если вам нужно значение для каждого терминала, тогда вам нужно сгруппировать для терминала и присоединиться к подзапросу

UPDATE dashboard.dummy 
SET duration_sec = 3600 - t.my_duration
FROM (  
    SELECT terminal_id , min(down_duration_sec)  my_duration
    FROM dashboard.down_event 
    WHERE terminal_id IN (SELECT terminal_id FROM dashboard.dummy)
    GROUP BY terminal_id
) t 
WHERE t.terminal_id = dashboard.dummy.terminal_id
AND availability_date IN (
    SELECT down_date 
    FROM dashboard.down_event 
    WHERE down_date IN ( SELECT availability_date FROM dashboard.dummy)
)

, а для отдельных значений следует использовать предложение DISTINCT

     UPDATE dashboard.dummy 
     SET duration_sec = 3600 - t.down_duration_sec 
     FROM ( 
        SELECT DISTINCT down_duration_sec, down_date, terminal_id 
        FROM dashboard.down_event 
        WHERE terminal_id IN (SELECT terminal_id FROM dashboard.dummy) 
     ) t 
     WHERE t.terminal_id = dashboard.dummy.terminal_id 
     AND dashboard.dummy.availability_date = t.down_date 
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...