首页 > 解决方案 > 将两个行值放入一列,将另一行值放入另一列,可以将更多行值添加到列中

问题描述

我只知道 SQL 的基础知识,最近在工作中我偶然发现了这种情况。我很难想象这个问题,但我会尽力解释它。我有两张桌子:

表 A:

IDA       SomeInfo 
-------  ----------
1        info1
2        info2
3        info3
4        info4

表 B:

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 的行中的两个不同 VarNames 放入一列,并将其他 VarNames 作为不同的列。每个都有各自的 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 中的结构,但我想通了,现在一切正常。感谢 TS 和 Gordon Linoff 的回答。他们帮了我很多。

标签: c#sqlwinforms

解决方案


在伪代码中 - 使用内联视图

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

毫无疑问,还有其他方法。我是老式的

我不确定什么是 DB 结构设置。例如,我不知道相同的 idIDA可以同时具有depthdepth2. 如果只有其中一个值是可能的,那么您可以更改过滤器,例如

select IDA, VarValue as depth from tableB where varName in ('depth', 'depth2')  

但如果两者都可能,我们需要另一个连接,并COALESCE在选择中。

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 ...

推荐阅读