这是我的sqlfiddle http://sqlfiddle.com/#!3/671c8/1。
以下是我的表格:
人
PID LNAME FNAME
1 Bob Joe
2 Smith John
3 Johnson Jake
4 Doe Jane
表1
PID VALUE
1 3
1 5
1 35
2 10
2 15
3 8
表2
PID VALUE
1 X1
1 X2
1 X3
2 Z1
3 X3
我正在尝试在一个人的ID上加入几个表格。这些表包含具有日期的事件,但日期可能会在表中匹配,也可能不匹配。因此,无论日期如何,我真正希望它以某种方式连接表格,这样当我得到结果时,具有最大行的表将是我的结果中的行数,而所有其他表将“适合”。例如
而不是笛卡尔产品:
PID LNAME FNAME THINGONE THINGTWO
1 Bob Joe 3 X1
1 Bob Joe 3 X2
1 Bob Joe 3 X3
1 Bob Joe 5 X1
1 Bob Joe 5 X2
1 Bob Joe 5 X3
1 Bob Joe 35 X1
1 Bob Joe 35 X2
1 Bob Joe 35 X3
我想要这样的事情:
PID LNAME FNAME THINGONE THINGTWO
1 Bob Joe 3 X1
1 Bob Joe 5 X2
1 Bob Joe 35 X3
我的sql声明:
SELECT
p.*,
t1.value as thingone,
t2.value as thingtwo
FROM
person p
left outer join table1 t1 on p.pid=t1.pid
left outer join table2 t2 on p.pid=t2.pid
;
答案 0 :(得分:2)
我无法理解为什么你想要这样做,但是......
您需要在table1和table2之间创建一个人工连接,然后将其链接到主表。一种方法是按顺序排列行。例如:
SELECT
p.pid, p.lname,p.fname, thingone, thingtwo
FROM
person p
left outer join
(
select ISNULL(t1.pid, t2.pid) as pid, t1.value as thingone, t2.value as thingtwo
from
(select *, ROW_NUMBER() over (partition by pid order by value) rn
from table1) t1
full outer join
(select *, ROW_NUMBER() over (partition by pid order by value) rn
from table2) t2
on t1.pid=t2.pid and t1.rn=t2.rn
) v
on p.pid = v.pid
答案 1 :(得分:0)
这比我想象的要棘手。无论两个列表的长度如何,挑战在于确保所有记录都出现。以下工作通过枚举每个列表并将其用于连接条件:
SELECT p.*,
t1.value as thingone,
t2.value as thingtwo
FROM person p left outer join
(select t1.*,
row_number() over (partition by pid order by pid) as seqnum,
count(*) over (partition by pid) as cnt
from table1 t1
) t1
on p.pid = t1.pid left outer join
(select t2.*, row_number() over (partition by pid order by pid) as seqnum,
count(*) over (partition by pid) as cnt
from table2 t2
) t2
on p.pid = t2.pid
WHERE t1.seqnum = t2.seqnum or
(t2.seqnum > t1.cnt) or
(t1.seqnum > t2.cnt) or
t1.seqnum is null or
t2.seqnum is null;
Here是对您的SQL Fiddle的一个小修改,它具有更好的测试数据。
编辑:
where
子句中的逻辑处理这些情况(按子句顺序):
这些是通过反复试验得出的,因为最初的条件不起作用:
on p.pid = t2.pid and t1.seqnum = t2.seqnum
这将为NULL
返回列表中额外元素的p.id
值。 Podliuska的方法也可以起作用;我刚刚开始沿着这条路走下去,where
条件可以解决这个问题。