Выбор столбцов на основе разницы между двумя строками

#database #postgresql

#База данных #postgresql

Вопрос:

Я работаю над базой данных PostgreSQL, которая выглядит следующим образом:

     -------------- --------------- --------------- --------------- 
   | avg_speed_p0 | avg_speed_p25 | avg_speed_p50 | avg_speed_p75 |
    -------------- --------------- --------------- --------------- 
1  |     85.15    |     87.23     |     84.16     |     85.44     |
2  |     78.63    |     82.76     |     78.01     |     83.15     |
    -------------- --------------- --------------- --------------- 
  

Где я рассчитал среднюю скорость днем (1) и ночью (2) для большого количества автомобилей в точках с интервалом 25 метров.

Я создал таблицу, используя:

 create table avg_speeds as
   select * from avg_speed_day
      union
   select * from avg_speed_night
  

Я попытался создать первичный ключ как day и night с помощью:

 alter table avg_speed_day add column time varchar
  

и затем:

 insert into avg_speed_day (time) values ('day')
  

но это не работает, а только дает мне:

     -------------- --------------- --------------- --------------- -------- 
   | avg_speed_p0 | avg_speed_p25 | avg_speed_p50 | avg_speed_p75 |  time  |
    -------------- --------------- --------------- --------------- -------- 
1  |     85.15    |     87.23     |     84.16     |     85.44     | [null] |
2  |     [null]   |     [null]    |     [null]    |     [null]    |   day  |
    -------------- --------------- --------------- --------------- -------- 
  

Я хотел бы получить таблицу, в которой вычисляется разница между днем (1) и ночью (2), и отображается только один раз, когда разница больше 5.

Вот так:

     --------------- ---------------- 
   | diff_speed_p0 | diff_speed_p50 |
    --------------- ---------------- 
1  |      6.52     |      6.15      |
    --------------- ---------------- 
  

Комментарии:

1. Вам нужен первичный ключ и способ определить, какая строка является первой, а какая второй (имеет значение для знака различия).

2. И как мне это сделать? 🙂

3. Вам не нужно делать это, вам уже нужно это иметь , иначе ваш вопрос не имеет для меня особого смысла…

4. Я создал таблицу с помощью: create table avg_speeds as select * from avg_speed_day union select * from avg_speed_night Поэтому у меня пока нет никакого первичного ключа. Но есть ли способ получить это? Я пытался с помощью: alter table avg_speed_day добавить переменную времени столбца, а затем: insert в значения avg_speed_day (time) (‘день’), но это не сработало.

5. Это дает только среднее значение: avg_speed_p0, avg_speed_p25, avg_speed_p50, avg_speed_p75 I время ——————- ———————— ———————— ———————— ——— 85.15 I 87.23 I 84.16 I 85.44 I [null] [нулевой] I [нулевой] I [нулевой] I [нулевой] Первый день

Ответ №1:

Ваши комментарии показывают, что вы получаете эти две строки из некоторых других таблиц или представлений.

Используйте их напрямую следующим образом:

 WITH day   AS (SELECT avg_speed_p0, avg_speed_p25, avg_speed_p50, avg_speed_p75
               FROM avg_speed_day),
     night AS (SELECT avg_speed_p0, avg_speed_p25, avg_speed_p50, avg_speed_p75
               FROM avg_speed_night)
SELECT CASE WHEN abs(day.avg_speed_p0 - night.avg_speed_p0) > 5
            THEN day.avg_speed_p0 - night.avg_speed_p0
       END AS avg_speed_p0,
       CASE WHEN abs(day.avg_speed_p25 - night.avg_speed_p25) > 5
            THEN day.avg_speed_p25 - night.avg_speed_p25
       END AS avg_speed_p25,
       CASE WHEN abs(day.avg_speed_p50 - night.avg_speed_p50) > 5
            THEN day.avg_speed_p50 - night.avg_speed_p50
       END AS avg_speed_p50,
       CASE WHEN abs(day.avg_speed_p75 - night.avg_speed_p75) > 5
            THEN day.avg_speed_p75 - night.avg_speed_p75
       END AS avg_speed_p75
FROM day CROSS JOIN night;
  

В SQL нет способа динамически опускать столбец.

Комментарии:

1. Большое вам спасибо. Я допустил опечатку, но теперь все работает. Спасибо.