我有一个问题,对于一个值,最多可以有两行。我只需要根据列值选择一行。下面的示例可以显示我的数据以及我要实现的目标。
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
答案 0 :(得分:0)
这里的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,因此您可能必须将上述代码分为两个步骤)
答案 1 :(得分:0)
您只需使用子查询和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
答案 2 :(得分:0)
执行此操作的一种方法是连接到任一建筑物,然后将其保留为“较高”的面积值(此处的作用是“国家”之后的“区”排序):
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
如果您不想依赖该排序顺序,则可以在order-by子句中使用case表达式使其更加明确。
您还可以进行两个外部联接,并使用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