SQL запрос - как использовать регистр? - PullRequest
0 голосов
/ 28 января 2020

Привет, у меня возникли проблемы с запросом - проблемы с фильтрацией данных - не знаю, как это сделать.

select lo.customer_no as station_num, lo."name" as station_name, fb.aggregation_type as data_source, fbh.balance_date as balance_day,
fbd.fuel_dis as fuel_dis, fb.sales_pos_manual as fuel_manual, p.product_name as product
from fuel_balance_data fbd
join fuel_balance fb on fb.id=fbd.fuel_balance_id 
join "location" lo on lo.id = fb.location_id 
join tank t on t.id = fb.tank_id 
join fuel_balance_header fbh on fbh.id=fuel_balance_header_id 
join product p on p.id=t.product_id
where fbh.location_id in (1031, 1035, 1026, 1024, 1008, 1009, 1006, 913, 320, 1010, 888, 417, 416, 440, 408, 486, 483, 402, 398, 
395, 393, 392, 391, 538, 386, 384, 383, 1033, 382, 377, 1030, 1034, 371, 369, 368, 365, 364, 363, 424, 464, 360, 357, 354, 353, 351, 347, 346, 1021, 343, 1002, 340, 1005, 445)
and fbd.gross_net = 'GROSS'
and cast(fbh.balance_date as date) between '2020-01-01' and  current_date - integer '1' 
order by balance_date, lo.customer_no, fb.aggregation_type desc

Таблица выглядит следующим образом:

+----------+---------------------------+----------+---------------------+-----------------+-----------+------------+
| station_num| station_name            | data_source | balance_day      | fuel_dis        | fuel_manual | product  |
+----------+---------------------------+----------+---------------------+-----------------+-----------+------------+
| 0000XXXX | LOCATION______ - 0000XXXX | MANUAL   | 2020-01-26 00:00:00 |          (NULL) | (NULL)    | VP Diesel  |
| 0000XXXX | LOCATION______ - 0000XXXX | MANUAL   | 2020-01-26 00:00:00 |          (NULL) | (NULL)    | SFS Diesel |
| 0000XXXX | LOCATION______ - 0000XXXX | MANUAL   | 2020-01-26 00:00:00 |          (NULL) | (NULL)    | SFS 95     |
| 0000XXXX | LOCATION______ - 0000XXXX | MANUAL   | 2020-01-26 00:00:00 |          (NULL) | (NULL)    | PB VPR 100 |
| 0000XXXX | LOCATION______ - 0000XXXX | MANUAL   | 2020-01-26 00:00:00 |          (NULL) | (NULL)    | PB 95 VP   |
| 0000XXXX | LOCATION______ - 0000XXXX | AUTO     | 2020-01-26 00:00:00 | 1001.8800000000 | (NULL)    | SFS 95     |
| 0000XXXX | LOCATION______ - 0000XXXX | AUTO     | 2020-01-26 00:00:00 |    0.0000000000 | (NULL)    | VP Diesel  |
| 0000XXXX | LOCATION______ - 0000XXXX | AUTO     | 2020-01-26 00:00:00 |  993.5300000000 | (NULL)    | SFS Diesel |
| 0000XXXX | LOCATION______ - 0000XXXX | AUTO     | 2020-01-26 00:00:00 |    0.0000000000 | (NULL)    | PB VPR 100 |
| 0000XXXX | LOCATION______ - 0000XXXX | AUTO     | 2020-01-26 00:00:00 |    0.0000000000 | (NULL)    | PB 95 VP   |
+----------+---------------------------+----------+---------------------+-----------------+-----------+------------+

Вот что я хочу:

  1. отфильтровать мой запрос - если продажи от dis не равны нулю, я хочу показывать только авто в день
  2. фильтровать мой запрос - если продажи от dis равны нулю, а продажи от ca sh не равны нулю - я хочу показывать только ручные за день
  3. фильтровать и редактировать таблицу - если в обоих случаях продажи от dis и продажи от ca sh равны нулю, я хочу показывать только руководство в день и изменить руководство на no_data

, как использовать в этом случае выписку с пропеллом? Поскольку я хочу запрашивать данные за весь месяц - некоторые дни получали только автоматически, некоторые - только вручную, а некоторые - no_data.

Ответы [ 2 ]

0 голосов
/ 28 января 2020

Кажется, вы хотите:

  1. aggregation_type / data_source, который оценивается по fuel_dis и fuel_manual, а не по столбцу aggregation_type.
  2. Рейтинг лучшего оцениваемого типа в зависимости от местоположения и дня, сохраняя только лучший рейтинг.

Для оценки используйте CASE WHEN. Для рейтинга вы можете использовать RANK. В вашем случае вы также можете ранжировать типы в алфавитном порядке, так как вы хотите, чтобы «AUTO» имел приоритет над «MANUAL» и «MANUAL» над «NO_DATA». Я показываю оба подхода.

Запрос:

select *
from
(
  select
    datasourced.*,
    -- either:
    min(real_data_source) over (partition by fbh.balance_date, lo.customer_no)
      as best_real_data_source,
    -- or:
    rank() over (partition by fbh.balance_date, lo.customer_no order by real_data_source)
      as rnk
  from
  (
    select 
      lo.customer_no as station_num,
      lo."name" as station_name,
      fbh.balance_date as balance_day,
      fbd.fuel_dis as fuel_dis,
      fb.sales_pos_manual as fuel_manual,
      p.product_name as product,
      case when fuel_dis is not null then 'AUTO'
           when fuel_manual is not null then 'MANUAL'
           else 'NO_DATA'
      end as real_data_source
    from fuel_balance_data fbd
    join fuel_balance fb on fb.id=fbd.fuel_balance_id 
    join "location" lo on lo.id = fb.location_id 
    join tank t on t.id = fb.tank_id 
    join fuel_balance_header fbh on fbh.id=fuel_balance_header_id 
    join product p on p.id=t.product_id
    where fbh.location_id in (1031, 1035, 1026, 1024, 1008, 1009, 1006, 913, 320, 1010,
                              888, 417, 416, 440, 408, 486, 483, 402, 398, 395, 393, 392,
                              391, 538, 386, 384, 383, 1033, 382, 377, 1030, 1034, 371,
                              369, 368, 365, 364, 363, 424, 464, 360, 357, 354, 353, 351,
                              347, 346, 1021, 343, 1002, 340, 1005, 445)
    and fbd.gross_net = 'GROSS'
    and fbh.balance_date >= '2020-01-01'
    and fbh.balance_date < current_date
  ) datasourced
) ranked
where 
  -- either:
  real_data_source = best_real_data_source
  -- or:
  rnk = 1
order by balance_date, customer_no;

(Я заменил ваше предложение даты на >= и <, как это обычно происходит с datetime. Это может включить СУБД использовать индекс и ускорить доступ.)

0 голосов
/ 28 января 2020
select 
CASE when ISNULL([sales from dis],'')<>'' then 'only auto per day'
WHEN ISNULL([sales from dis],'')='' and ISNULL([sales from cash],'')<>'' then 'only 
manual per day'
WHEN ISNULL([sales from dis],'')='' and ISNULL([sales from cash],'')='' then 'only 
manual per day and change manual to no_data' end as [Result],* 
from
(select 
lo.customer_no as [location number],
lo."name" as [location name],
fb.aggregation_type as [datatype(man/auto)],
fbh.balance_date,
fbd.fuel_dis as [sales from dis],
fb.sales_pos_manual as [sales from cash],
p.product_name as [product type] 
from fuel_balance_data fbd 
join fuel_balance fb on fb.id=fbd.fuel_balance_id  
join "location" lo on lo.id = fb.location_id  
join tank t on t.id = fb.tank_id  
join fuel_balance_header fbh on fbh.id=fuel_balance_header_id  
join product p on p.id=t.product_id 
where fbh.location_id  = 357
and fbd.gross_net = 'GROSS' 
and fbh.balance_date  < current_date - integer '1' 
order by balance_date desc)A
...