将两行值放入一列,将另一行值放入另一列,并可以将更多行值添加到列中
Making TWO row values into one column, and another row value another column, with the possibility of adding more row values into columns
我只知道SQL的基础知识,最近在工作中偶然发现了这种情况。我很难想象这个问题,但我会尽力解释它。
我有两个表:
Table答:
IDA SomeInfo
------- ----------
1 info1
2 info2
3 info3
4 info4
Table乙:
IDB IDA VarName VarValue
------- ------- ------- ---------
1 1 Depth 2
2 1 Length 10
3 2 Depth2 3
4 2 Length 12
5 2 Height 35
6 3 Depth2 2
7 3 Length 11
8 3 Height 38
9 4 Depth 4
10 4 Length 16
我需要加入他们才能获得以下结果:
Depth
IDA SomeInfo Depth2 Length Height
------- -------- ------- ------- ---------
1 info1 2 10 0
2 info2 3 12 35
3 info3 2 11 38
4 info4 4 16 0
如您所见,我需要将 B 的行中的两个不同的 VarName 放入一列中,并将其他 VarName 放入不同的列中。每个都有各自的 VarValue 和 IDA,然后当 IDA 没有一些 VarVal 时,它需要为 0。我的 c# 字符串查询中有以下代码,当我只需要处理“深度”和“深度 2”:
SELECT
A.IDA, A.SomeInfo,
CASE
WHEN (B.VarValue IS NULL) THEN 0
WHEN B.VarName = 'Depth' OR B.VarName = 'Depth2' THEN B.VarValue
END AS Depth
FROM A LEFT JOIN
(
SELECT B.IDA, B.VarName, B.VarValue FROM B
WHERE (B.VarName = 'Depth' OR B.VarName = 'Depth2')
) B ON (A.IDA = B.IDA)
然后我需要添加更多的VarNames,所以我更改了代码如下:
SELECT DISTINCT
A.IDA, A.SomeInfo,
CASE
WHEN (B.VarName = 'Depth' OR B.VarName = 'Depth2') AND B.VarValue IS NULL THEN 0
WHEN B.VarName = 'Depth' OR B.VarName = 'Depth2' THEN B.VarValue
END AS Depth,
CASE
WHEN B.VarName = 'Length' AND B.VarValue IS NULL THEN 0
WHEN B.VarName = 'Length' THEN B.VarValue
END AS Length
CASE
WHEN B.VarName = 'Height' AND B.VarValue IS NULL THEN 0
WHEN B.VarName = 'Height' THEN B.VarValue
END AS Height
FROM A LEFT JOIN
(
SELECT B.IDA, B.VarName, B.VarValue FROM B
WHERE (B.VarName = 'Depth' OR B.VarName = 'Depth2' OR B.VarName = 'Length' OR
B.VarName = 'Height')
) B ON (A.IDA = B.IDA)
但现在我为每个 VarName 得到一行。我应该怎么做才能完成这项工作?
编辑:这个问题中的两个答案都适用于我给出的示例,但标记的答案对我来说效果最好。我有一个与 DB2 相关的问题以及数据在 as400 中的结构,但我想通了,现在一切正常。感谢 T.S。和戈登·利诺夫 (Gordon Linoff) 的回答。他们帮了我很多。
在伪代码中 - 使用内联视图
select a.IDA, a.SomeInfo, dep.depth, hei.Height, le.Length
from
TableA a left join
(select IDA, VarValue as depth from tableB where varName = 'depth' ) dep
on a.ida = dep.ida letf join
(select IDA, VarValue as height from tableB where varName = 'height' ) hei
on a.ida = hei.ida letf join
(select IDA, VarValue as Length from tableB where varName = 'Length' ) le
on a.ida = le.ida
毫无疑问,还有其他方法。我是老派
我不确定什么是数据库结构设置。例如,我不知道相同的 id IDA
可以同时具有 depth
和 depth2
。如果这些值中只有一个是可能的,那么您可以像
这样更改过滤器
select IDA, VarValue as depth from tableB where varName in ('depth', 'depth2')
但是如果两者都可行,我们需要另一个连接,COALESCE
in select。
Select ...., COALESCE(dep.depth, dep2.depth2) as depth
....
(select IDA, VarValue as depth from tableB where varName = 'depth' ) dep
on a.ida = dep.ida letf join
(select IDA, VarValue as depth2 from tableB where varName = 'depth2' ) dep2
on a.ida = dep2.ida letf join ...
您可以使用条件聚合:
select a.ida, a.someinfo,
sum(case when varname in ('Depth', 'Depth2') then varvalue end) as depth,
sum(case when varname in ('Length') then varvalue end) as length,
sum(case when varname in ('Height') then varvalue end) as depth
from tablea a left join
tableb b
on a.ida = b.ida
group by a.ida, a.someinfo;
Here 是一个 db<>fiddle.
我只知道SQL的基础知识,最近在工作中偶然发现了这种情况。我很难想象这个问题,但我会尽力解释它。 我有两个表:
Table答:
IDA SomeInfo
------- ----------
1 info1
2 info2
3 info3
4 info4
Table乙:
IDB IDA VarName VarValue
------- ------- ------- ---------
1 1 Depth 2
2 1 Length 10
3 2 Depth2 3
4 2 Length 12
5 2 Height 35
6 3 Depth2 2
7 3 Length 11
8 3 Height 38
9 4 Depth 4
10 4 Length 16
我需要加入他们才能获得以下结果:
Depth
IDA SomeInfo Depth2 Length Height
------- -------- ------- ------- ---------
1 info1 2 10 0
2 info2 3 12 35
3 info3 2 11 38
4 info4 4 16 0
如您所见,我需要将 B 的行中的两个不同的 VarName 放入一列中,并将其他 VarName 放入不同的列中。每个都有各自的 VarValue 和 IDA,然后当 IDA 没有一些 VarVal 时,它需要为 0。我的 c# 字符串查询中有以下代码,当我只需要处理“深度”和“深度 2”:
SELECT
A.IDA, A.SomeInfo,
CASE
WHEN (B.VarValue IS NULL) THEN 0
WHEN B.VarName = 'Depth' OR B.VarName = 'Depth2' THEN B.VarValue
END AS Depth
FROM A LEFT JOIN
(
SELECT B.IDA, B.VarName, B.VarValue FROM B
WHERE (B.VarName = 'Depth' OR B.VarName = 'Depth2')
) B ON (A.IDA = B.IDA)
然后我需要添加更多的VarNames,所以我更改了代码如下:
SELECT DISTINCT
A.IDA, A.SomeInfo,
CASE
WHEN (B.VarName = 'Depth' OR B.VarName = 'Depth2') AND B.VarValue IS NULL THEN 0
WHEN B.VarName = 'Depth' OR B.VarName = 'Depth2' THEN B.VarValue
END AS Depth,
CASE
WHEN B.VarName = 'Length' AND B.VarValue IS NULL THEN 0
WHEN B.VarName = 'Length' THEN B.VarValue
END AS Length
CASE
WHEN B.VarName = 'Height' AND B.VarValue IS NULL THEN 0
WHEN B.VarName = 'Height' THEN B.VarValue
END AS Height
FROM A LEFT JOIN
(
SELECT B.IDA, B.VarName, B.VarValue FROM B
WHERE (B.VarName = 'Depth' OR B.VarName = 'Depth2' OR B.VarName = 'Length' OR
B.VarName = 'Height')
) B ON (A.IDA = B.IDA)
但现在我为每个 VarName 得到一行。我应该怎么做才能完成这项工作?
编辑:这个问题中的两个答案都适用于我给出的示例,但标记的答案对我来说效果最好。我有一个与 DB2 相关的问题以及数据在 as400 中的结构,但我想通了,现在一切正常。感谢 T.S。和戈登·利诺夫 (Gordon Linoff) 的回答。他们帮了我很多。
在伪代码中 - 使用内联视图
select a.IDA, a.SomeInfo, dep.depth, hei.Height, le.Length
from
TableA a left join
(select IDA, VarValue as depth from tableB where varName = 'depth' ) dep
on a.ida = dep.ida letf join
(select IDA, VarValue as height from tableB where varName = 'height' ) hei
on a.ida = hei.ida letf join
(select IDA, VarValue as Length from tableB where varName = 'Length' ) le
on a.ida = le.ida
毫无疑问,还有其他方法。我是老派
我不确定什么是数据库结构设置。例如,我不知道相同的 id IDA
可以同时具有 depth
和 depth2
。如果这些值中只有一个是可能的,那么您可以像
select IDA, VarValue as depth from tableB where varName in ('depth', 'depth2')
但是如果两者都可行,我们需要另一个连接,COALESCE
in select。
Select ...., COALESCE(dep.depth, dep2.depth2) as depth
....
(select IDA, VarValue as depth from tableB where varName = 'depth' ) dep
on a.ida = dep.ida letf join
(select IDA, VarValue as depth2 from tableB where varName = 'depth2' ) dep2
on a.ida = dep2.ida letf join ...
您可以使用条件聚合:
select a.ida, a.someinfo,
sum(case when varname in ('Depth', 'Depth2') then varvalue end) as depth,
sum(case when varname in ('Length') then varvalue end) as length,
sum(case when varname in ('Height') then varvalue end) as depth
from tablea a left join
tableb b
on a.ida = b.ida
group by a.ida, a.someinfo;
Here 是一个 db<>fiddle.