使用MSSQL 2012,我有三个表。表0有一个值,我用它来连接其他一些表,如下所示:
Table0
----------
keyval
1
Table1
----------
keyval someval
1 blah
1 blah1
Table2
----------
keyval someotherval
1 woo
1 woo1
1 woo2
现在,如果我执行以下查询
SELECT Table1.someval AS val1, Table2.someotherval AS val2
FROM Table0
INNER JOIN Table1 ON Table0.keyval = Table1.keyval
INNER JOIN Table2 ON Table0.keyval = Table2.keyval
WHERE Table0.keyval = '1'
我得到以下结果:
val1 val2
----------
blah woo
blah woo1
blah woo2
blah1 woo
blah1 woo1
blah1 woo2
我的问题是,如何确保 每个值仅在结果中显示一次? 我想知道如何运行查询以获得以下结果
val1 val2
----------
blah woo
blah1 woo1
null woo2
我尝试了所有不同类型的连接,但效果不佳。我有一种感觉,我需要UNION某处,但我不知道在哪里
答案 0 :(得分:1)
您似乎想要一个笛卡尔积的随机子集,其中每个值都表示一次,所以这样的事情应该这样做:
with t0(k) as (
select 1
), t1(k,v1) as (
select 1,'blah'
union
select 1,'blah1'
), t2(k,v2) as (
select 1,'woo'
union
select 1,'woo1'
union
select 1,'woo2'
), t3(k,v1,rn) as (
select t1.k, v1, row_number() over (order by t1.v1) as rn1
from t1
join t0
on t0.k = t1.k
), t4(k,v2,rn) as (
select t2.k, v2, row_number() over (order by t2.v2) as rn2
from t2
join t0
on t0.k = t2.k
)
select t3.v1, t4.v2
from t3
full join t4
on t3.k = t4.k
and t3.rn = t4.rn
V1 V2
blah woo
blah1 woo1
(null) woo2
编辑:使用表而不是CTE t0,t1和t2
create table table0 (k int not null);
insert into table0 (k) select 1;
create table table1 (k int not null, v1 varchar(5) not null);
create table table2 (k int not null, v2 varchar(5) not null);
insert into table1 (k,v1)
select 1,'blah'
union
select 1,'blah1'
union
select 1, 'jojo'
union
select 1, 'jojo1';
insert into table2 (k,v2)
select 1,'woo'
union
select 1,'woo1'
union
select 1,'woo2';
with t3(k,v1,rn) as (
select t1.k, v1, row_number() over (order by t1.v1) as rn1
from table1 t1
join table0 t0
on t0.k = t1.k
), t4(k,v2,rn) as (
select t2.k, v2, row_number() over (order by t2.v2) as rn2
from table2 t2
join table0 t0
on t0.k = t2.k
)
select t3.v1, t4.v2
from t3
full join t4
on t3.k = t4.k
and t3.rn = t4.rn;
V1 V2
blah woo
blah1 woo1
jojo woo2
jojo1 (null)
delete from table1 where v1 like 'joj%';
with t3(k,v1,rn) as (
select t1.k, v1, row_number() over (order by t1.v1) as rn1
from table1 t1
join table0 t0
on t0.k = t1.k
), t4(k,v2,rn) as (
select t2.k, v2, row_number() over (order by t2.v2) as rn2
from table2 t2
join table0 t0
on t0.k = t2.k
)
select t3.v1, t4.v2
from t3
full join t4
on t3.k = t4.k
and t3.rn = t4.rn;
V1 V2
blah woo
blah1 woo1
(null) woo2
答案 1 :(得分:0)
我觉得将唯一值拉入单个列会容易得多, 然后使用第二个“假”'列,用于指定值的来源。 由于他们不一定要互相配对,因此没有理由将它们成对列出。
SELECT DISTINCT Table1.someval AS val,'Table1' As source
FROM Table1
WHERE Table1.keyval = '1'
UNION
SELECT DISTINCT Table2.someval as val, 'Table2' As source
FROM Table2
WHERE Table2.keyval = '1'
请注意,在这种情况下,我完全删除了Table0
,数据设置方式与问题相符,Table0
唯一重要的时间是,如果没有keyval = 1 in Table0
,在这种情况下,您将无法获得任何结果。
但是,如果这对你很重要,
SELECT DISTINCT Table1.someval AS val,'Table1' As source
FROM Table1
INNER JOIN Table0 ON Table0.keyval = Table1.keyval
WHERE Table0.keyval = '1'
UNION
SELECT DISTINCT Table2.someval as val, 'Table2' As source
FROM Table2
INNER JOIN Table0 ON Table0.keyval = Table2.keyval
WHERE Table0.keyval = '1'
答案 2 :(得分:0)
基于给定的数据,我越接近:
select s.val1, s.val2
from (
select t1.someval as val1
, null as val2
from table1 t1
union
select null as val1
, t2.someotherval as val2
from table2 t2
) s
结果如下:
val1 | val2
--------------
blah | (null)
blah1 | (null)
(null)| woo
(null)| woo1
(null)| woo2
请参阅SQL Fiddle。
否则,你可以做到这一点:
val
-------
blah
blah1
woo
woo1
woo2
使用此查询:
select t1.someval as val
from table1 t1
union
select t2.someotherval
from table2 t2
请参阅SQL Fiddle。
虽然两者都不是理想的结果集,但这是我能用给定输入得到的最接近的结果。
答案 3 :(得分:-2)
如果要查看已连接表格的NULL结果,请使用' LEFT JOIN'。
SELECT Table1.someval AS val1, Table2.someotherval AS val2
FROM Table0
LEFT JOIN Table1 ON Table0.keyval = Table1.keyval
LEFT JOIN Table2 ON Table0.keyval = Table2.keyval
WHERE Table0.keyval = '1'