我有一个项目清单,按存款,库存,采购订单,销售订单,消费或生产预测等。我想设置一个查询每个项目给我所有这些信息,存款存款。显然,并不是说每个项目都有这些信息。
例如,考虑以下表格:
T1
| REF |
|--------|
| 1 |
T2
| REF | DEPOT |
|--------|--------|
| 1 | A |
| 1 | B |
T3
| REF | DEPOT |
|--------|--------|
| 1 | A |
| 1 | C |
T4
| REF | DEPOT |
|--------|--------|
| 1 | B |
| 1 | C |
| 1 | D |
如果我只采用前三个表(刚开始),我找不到比:
SELECT T1.ref AS T1ref
, T2.ref AS T2ref, T2.depot AS T2depot
, T3.ref AS T3ref, T3.depot AS T3depot
FROM T1
LEFT JOIN T2
ON T2.ref = T1.ref
FULL JOIN T3
ON T3.ref = T1.ref
AND T3.depot = T2.depot
输出:
| T1REF | T2REF | T2DEPOT | T3REF | T3DEPOT |
|--------|--------|---------|--------|---------|
| 1 | 1 | A | 1 | A |
| 1 | 1 | B | (null) | (null) |
| (null) | (null) | (null) | 1 | C |
我想要的是什么:
| T1REF | T2REF | T2DEPOT | T3REF | T3DEPOT |
|--------|--------|---------|--------|---------|
| 1 | 1 | A | 1 | A |
| 1 | 1 | B | (null) | (null) |
| 1 | (null) | (null) | 1 | C |
必须有一个干净的方法来做到这一点,但我没有找到任何东西。而且很难在此找到材料。
有人有提示吗?
sqlfiddle:http://sqlfiddle.com/#!3/19014/2
谢谢你, 大卫。
修改
用T4:
| T1REF | T2REF | T2DEPOT | T3REF | T3DEPOT | T4REF | T4DEPOT |
|--------|--------|---------|--------|---------|--------|---------|
| 1 | 1 | A | 1 | A | (null) | (null) |
| 1 | 1 | B | (null) | (null) | 1 | B |
| 1 | (null) | (null) | 1 | C | 1 | C |
| 1 | (null) | (null) | (null) | (null) | 1 | D |
我应该用更好的名字命名我的表:T1 =项目,T2 =股票,T3 =购买,T4 =卖出。因此,T1将始终拥有所有参考,以及我需要的许多其他信息。
答案 0 :(得分:1)
您可以使用coalesce()
修正您的特定查询:
SELECT coalesce(T1.ref, t2.ref, t3.ref) AS T1ref
但是,我发现使用我关注的列表和组合更容易,而不是使用full outer join
。在这种情况下,您似乎关心所有表中的t1.ref
和depots
。也许这更接近你真正想做的事情:
SELECT t1ref.ref,
T2.ref AS T2ref, T2.depot AS T2depot,
T3.ref AS T3ref, T3.depot AS T3depot
FROM (select ref from T1 union
select ref from T2 union
select ref from T3
) t1ref cross join
(select depot from T2 union
select depot from t3
) d LEFT JOIN T2
ON T2.ref = T1ref.ref and
t2.depot = d.depot LEFT JOIN
T3
ON T3.ref = T1ref.ref AND
T3.depot = d.depot --OR T2.depot IS NULL)
答案 1 :(得分:0)
Gordon Linoff所述的所有4个表和Coalesce的示例
;with[T1]([REF])as(
select * from (values(1),(2))[A]([REF])
),
[T2]([REF],[DEPOT])as(
select*from(values
(1,'A'),
(1,'B'),
(1,'E')
)[a]([REF],[DEPOT])
),
[T3]([REF],[DEPOT])as(
select*from(values
(1,'A'),
(1,'C')
)[a]([REF],[DEPOT])
),
[T4]([REF],[DEPOT])as(
select*from(values
(1,'B'),
(1,'C'),
(1,'D'),
(1,'E')
)[a]([REF],[DEPOT])
)
select
*
from [T1]
outer apply (
select
T2.REF T2REF,
T2.DEPOT T2DEPOT,
T3.REF T3REF,
T3.DEPOT T3DEPOT,
T4.REF T4REF,
T4.DEPOT T4DEPOT
from T2
full outer join T3 on
T2.REF = T3.REF and
T2.DEPOT = T3.DEPOT
full outer join T4 on
COALESCE(T3.REF,T2.REF) = T4.REF and
COALESCE(T3.DEPOT,T2.DEPOT) = T4.DEPOT
where
COALESCE(T2.REF,T3.REF,T4.REF) = T1.REF
) TR
答案 2 :(得分:0)
在你的帮助下,我发现如果我忘记了一段时间的项目信息(表T1),我几乎可以获得我想要的东西:
SELECT *
FROM T2
FULL JOIN T3
ON T3.ref = T2.ref
AND T3.depot = T2.depot
FULL JOIN T4
ON (
T4.ref = T2.ref
AND T4.depot = T2.depot
)
OR (
T4.ref = T3.ref
AND T4.depot = T3.depot
)
它给出了:
| T2REF | T2DEPOT | T3REF | T3DEPOT | T4REF | T4DEPOT |
|--------|---------|--------|---------|--------|---------|
| 1 | A | 1 | A | (null) | (null) |
| 1 | B | (null) | (null) | 1 | B |
| (null) | (null) | 1 | C | 1 | C |
| (null) | (null) | (null) | (null) | 1 | D |
之后我必须得到T1信息:
SELECT *
FROM T2
FULL JOIN T3
ON T3.ref = T2.ref
AND T3.depot = T2.depot
FULL JOIN T4
ON (
T4.ref = T2.ref
AND T4.depot = T2.depot
)
OR (
T4.ref = T3.ref
AND T4.depot = T3.depot
)
INNER/RIGHT JOIN T1
ON T1.ref = COALESCE(T2.ref, T3.ref, T4.ref)
获得:
| T2REF | T2DEPOT | T3REF | T3DEPOT | T4REF | T4DEPOT | T1REF |
|--------|---------|--------|---------|--------|---------|--------|
| 1 | A | 1 | A | (null) | (null) | 1 |
| 1 | B | (null) | (null) | 1 | B | 1 |
| (null) | (null) | 1 | C | 1 | C | 1 |
| (null) | (null) | (null) | (null) | 1 | D | 1 |
为了好玩(并且更好地理解这个请求后者的目的),如果我把T1作为第一个表,我仍然试图让这个工作......
(太糟糕的sqlfiddle似乎没有管理几个具有相同名称的字段......)