Выбор строк на основе значений столбцов - PullRequest
0 голосов
/ 18 апреля 2019

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

Table Item with the following information
Item   Dist_Building     Country_Building
I123   B123               B245   
I980   B980               B345
I780   B780               B445
Table item_info with the following columns
Item_number Building_Nbr Building_Area  Value
I123         B123        District        10
I123         B245        Country         20
I980         B980        District        50
I780         B445        Country         20

Выберите элементы из таблицы «Предмет» и проверьте наличие соответствующей информации о здании, представленной в таблице «Элемент_инфо». Если для определенного элемента значения присутствуют на уровне округа и страны, тогда выберите значение VALUE уровня округа, в противном случае выберите значение VALUE уровня страны (т.е. строка с районом района будет иметь приоритет над страной)

Item_number Value
I123         10
I980         50
I780         20

Ответы [ 3 ]

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

Вы можете достичь своей цели, просто используя подзапросы и функцию NVL:

SELECT Item
     , NVL((SELECT VALUE FROM item_info ii 
             WHERE ii.item_number = i.item
               AND ii.Building_Nbr = i.Dist_Building)
          ,(SELECT VALUE FROM item_info ii 
             WHERE ii.item_number = i.item
               AND ii.Building_Nbr = i.Country_Building)) VALUE
  FROM Item i
0 голосов
/ 18 апреля 2019

Один из способов сделать это - объединить любое здание с последующим сохранением с более высоким значением площади (которое здесь сортируется как «Район» после «Страна»):

select i.item,
  max(ii.value) keep (dense_rank last order by ii.building_area) as value 
from item i
join item_info ii on ii.item_number = i.item
and (
  (ii.building_nbr = i.dist_building and ii.building_area = 'District')
  or (ii.building_nbr = i.country_building and ii.building_area = 'Country')
)
group by i.item;

ITEM      VALUE
---- ----------
I123         10
I780         20
I980         50

Вы можете сделать это более явным с помощью выражения case в предложении order-by, если вы не хотите полагаться на этот порядок сортировки.

Вы также можете сделать два внешних соединения и использовать coalesce длявыберите тот, который вы хотите:

select i.item,
  coalesce(iid.value, iic.value) as value
from item i
left join item_info iid on iid.item_number = i.item
and iid.building_nbr = i.dist_building
and iid.building_area = 'District'
left join item_info iic on iic.item_number = i.item
and iic.building_nbr = i.country_building
and iic.building_area = 'Country';

ITEM      VALUE
---- ----------
I123         10
I780         20
I980         50

db <> скрипка

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

важны Dist_Building, Country_Building и Building_Nbr здесь?Похоже, что нет, и в этом случае, если вы создадите новую таблицу из таблицы item_info, например, так ...

select 
  item_number
  , building_nbr
  , sum(case when building_area = 'District' then value end) as District_Val
  , sum(case when building_area = 'Country' then value end) as Country_Val
  , coalesce(District_Val, Country_Val) as Value 
into new_item_info
from item_info
group by 
  1,2 

, вы сможете просто присоединить ее к таблице item.,(Я не очень знаком с Oracle SQL, поэтому вам, возможно, придется разбить приведенный выше код на два этапа)

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