我们有2张桌子; table1,table2。
table1 :
CNTY | ZIP | SERVICE 111 | 1234 | N 111 | | Y 112 | | Y
table2 :
CNTY | ZIP | 111 | 1234 | 111 | 4321 | 112 | 4433 |
我们正在使用oracle并尝试以下查询 -
SELECT t1.SERVICE
FROM table1 t1
WHERE t1.CNTY IN (SELECT t2.CNTY
FROM table2 t2
WHERE t2.ZIP = '4433')
返回Y是预期的行为。但是如果我们发送t2.zip='4321'
它返回2行,但我们期待一行(Y)。另外,如果我们发送应返回“N”的t2.zip='1234'
。但是,上面的查询返回2行。
我是一个非常新的数据库方面。我们尝试过,但无法在一个声明中得到它。有没有办法达到预期的行为?
基本上我对查询的期望是 -
SERVICE
返回table1
值。如果它在ZIP
中找到table1
,则应返回匹配zip的SERVICE
值。 ZIP
中没有匹配的table1
,那么它应该会在CNTY
中找到与给定zip相关联的table2
,然后取出CNTY
来自table2
的值,它应在SERVICE
中找到匹配table1
的{{1}}值并返回该值。 例如:对于ZIP 4321,table1中没有匹配的条目,但是在table2中4321与111相关联,因此对于table1中的111,SERVICE值为Y.因此,查询应该返回Y.
答案 0 :(得分:1)
我不确定为什么你只想要一排。让我们来看看查询的作用:
SELECT t2.CNTY FROM table2 t2 WHERE t2.ZIP = '4321'
返回单个值:111,对应于以下行:
111 | 4321 |
所以完整的查询等同于
SELECT t1.SERVICE FROM table1 t1 WHERE t1.CNTY IN (111)
然后返回这两行的服务,因为它们的CNTY都等于111:
111 | 1234 | N
111 | | Y
答案 1 :(得分:0)
它返回两个因为你在table1中有两行,城市111
select t1.* from
table1 t1
join table2 t2 on t2.city = t1.city and (t2.zip = t1.zip or t2.zip is null)
现在您加入了城市和邮政编码,或者没有邮政编码。
这将只返回一行,但如果有两个城市行,111并且没有邮政编码,那么它将返回2
(注意:没有测试过这个SQL - 我已经从内存中完成了它;))
答案 2 :(得分:0)
有没有办法达到预期的行为?
是的,您可以加入CNTY
和ZIP
上的表格。
SELECT t1.SERVICE
FROM table1 t1, table2 t2
WHERE t1.CNTY = t2.CNTY AND t1.ZIP = t2.ZIP
AND t2.ZIP = '1234'
然而,上述仍然不适用于ZIP'4321'。为此,连接必须更复杂。
SELECT COALESCE(t1a.SERVICE, t1b.SERVICE) AS SERVICE
FROM table2 t2
LEFT JOIN table1 t1a ON t1a.CNTY = t2.CNTY AND t1a.ZIP = t2.ZIP
LEFT JOIN table1 t1b ON t1b.CNTY = t2.CNTY AND COALESCE(t1b.ZIP, '') = ''
WHERE t2.ZIP = '4321'
第二个查询适用于所有情况。
答案 3 :(得分:0)
select service from (
select row_number() over (order by t1.zip nulls last) rn, service
from table1 t1
join table2 t2 on t2.cnty = t1.cnty and (t2.zip = t1.zip or t1.zip is null)
where coalesce(t1.zip, t2.zip) = '1234')
where rn=1
如果row_number
有两行, join
用于对记录进行排序,例如zip = 1234。
查询对每个zip都正常工作。
您也可以使用:
select
case
when exists (select 1 from table1 where zip='1234')
then
(select service from table1 where zip='1234')
else
(select service from table1 where zip is null
and cnty = (select cnty from table2 where zip='1234'))
end service
from dual
喜欢这里:
with zips as (select '1234' zip from dual
union select '4321' from dual
union select '4433' from dual
union select 'TEST' from dual)
select zips.zip,
case
when exists (select 1 from table1 where zip=zips.zip)
then
(select service from table1 where zip=zips.zip)
else
(select service from table1 where zip is null and cnty =
(select cnty from table2 where zip=zips.zip))
end service
from zips
zip service
1234 N
4321 Y
4433 Y
TEST null