让我试着解释一下这个场景。我有两张桌子A(列 - A1,A2,A3)& B(列 - B1,B2,B3)。我需要在A1.B2上将表A与表B连接起来。对于每个连接,表B具有一个或两个具有不同B3(X或Y)值的记录。我想编写一个查询,其中JOIN查询需要选择B3 = X的行(如果没有其他行,B3 = Y);如果存在两行(B3 = X& B3 = Y),则查询只需要选择B3 = Y的行(忽略B3 = X的行)。
让我试着给表和表格赋予一些价值。再解释一下。
Table A ******** A1 A2 A3 1 11 111 2 22 222 3 33 333 4 44 444 Table B ******** B1 B2 B3 6 1 X 7 1 Y 8 2 X 9 3 X 10 3 Y 11 4 X Again.. JOIN is on A1.B2. The result should be as following, JOIN Results ************* A1 A2 A3 B1 B2 B3 1 11 111 7 1 Y 2 22 222 8 2 X 3 33 333 10 3 Y 4 44 444 11 4 X
如果你们对我的问题有任何澄清,请告诉我。
提前致谢。 瑜珈
答案 0 :(得分:3)
如果您按加入列进行分区并按“拣配顺序”列进行排序,则可以使用ROW_NUMBER
功能从表B中选择行:
SELECT b1, b2, b3,
ROW_NUMBER() OVER (PARTITION BY b2 ORDER BY b3 DESC) as rn
FROM b;
1 Y 1
1 X 2
2 X 1
3 Y 1
3 X 2
4 X 1
然后您可以过滤第一行,即rn=1
:
SELECT b1, b2, b3
FROM (SELECT b1, b2, b3,
ROW_NUMBER() OVER (PARTITION BY b2 ORDER BY b3 DESC) as rn
FROM b)
WHERE rn=1;
7 1 Y
8 2 X
10 3 Y
11 4 X
然后可以将已过滤的行连接到表a:
SELECT *
FROM a
JOIN (
SELECT b1, b2, b3
FROM (SELECT b1, b2, b3,
ROW_NUMBER() OVER (PARTITION BY b2 ORDER BY b3 DESC) as rn
FROM b
)
WHERE rn=1
) bfilter ON a.a1 = bfilter.b2;
1 11 111 7 1 Y
2 22 222 8 2 X
3 33 333 10 3 Y
4 44 444 11 4 X
如果'X'和'Y'不是实际值,您可以使用ORDER
语句扩展CASE
子句以允许使用一般值:
ROW_NUMBER() OVER (PARTITION BY b2 ORDER BY
CASE b3 WHEN 'Y' THEN 1
WHEN 'X' THEN 2
...
END ASC)
编辑:
SELECT a1, a2, a3, b1, b2, b3
FROM (
SELECT a1, a2, a3, b1, b2, b3,
ROWNUMBER() OVER (PARTITION BY a1 ORDER BY
CASE WHEN a2=... AND b3=... THEN 1
WHEN a2=... AND b3=... THEN 2
...
END ASC)
FROM a JOIN b ON a.a1 = b.b2
)
WHERE rn = 1;
答案 1 :(得分:1)
您可以按如下方式使用左外连接
select A.A1, A.A2, A.A3,
nvl(BT1.B1, BT2.B1),
nvl(BT1.B2, BT2.B2),
nvl(BT1.B3, BT2.B3) from A
left outer join B BT1 on A.A1 = BT1.B2 and BT1.B3 = 'Y'
left outer join B BT2 on A.A1 = BT2.B2 and BT2.B3 = 'X'
各种联接的一个很好的解释是http://www.codinghorror.com/blog/2007/10/a-visual-explanation-of-sql-joins.html
答案 2 :(得分:0)
以下是我将如何做到这一点:
这样,只有在没有按字母顺序排列的较高值(Y)时,才能确保选择X
答案 3 :(得分:0)
使用UNION
select a.*,b.* from a,b
where a.a1=b.b2
and b.b3='Y'
union
select a.*,b.* from a,b
where a.a1=b.b2
and not exists (select bb.br from b bb where bb.b2=a.a1 and bb.b3='Y')
没有UNION
select a.*,b.* from a,b
where a.a1=b.b2
and (b.b3='Y'
or not exists (select bb.b3 from b bb where bb.b2=a.a1 and bb.b3='Y'))
这里的约束是B对于每个A的行
恰好有1或2行