使用置换表填补空白

时间:2017-03-24 20:49:24

标签: sql sql-server tsql permutation

我有一张我希望存在的排列表。然后我有一张实际数据表。我试图以这样的方式加入排列表,即存在所有排列,如果存在实际数据,那么VALUE就是它,否则它就是null。

CREATE TABLE Data
    ([ID] int, [NAME] varchar(8), [FACTOR_VALUE] numeric, [CLASS] int)
;

INSERT INTO Data
    ([ID], [NAME], [FACTOR_VALUE], [CLASS])
VALUES
    (1, 'FLEX_AVG', 12.1, 2),
    (1, 'FLEX_AVG', 34.4, 1),
    (2, 'FLEX_AVG', 22.1, 1)
;

CREATE TABLE Permutations
    ([CLASS] int, [NAME] varchar(9))
;

INSERT INTO Permutations
    ([CLASS], [NAME])
VALUES
    (1, 'FLEX_AVG'),
    (2, 'FLEX_AVG'),
    (3, 'FLEX_AVG'),
    (1, 'RIGID_AVG'),
    (2, 'RIGID_AVG'),
    (3, 'RIGID_AVG')
;

这是我的尝试:

SELECT DISTINCT
    X.ID,
    A.NAME,
    IIF(X.Class = A.Class AND X.NAME = A.NAME, FACTOR_VALUE, NULL) AS FACTOR_VALUE,
    A.CLASS
FROM Data X
LEFT JOIN Permutations A
ON 1=1

但这会产生:

ID  NAME    FACTOR_VALUE    CLASS
1   FLEX_AVG    NULL    1
1   FLEX_AVG    NULL    2
1   FLEX_AVG    NULL    3
1   FLEX_AVG    12.1    2
1   FLEX_AVG    34.4    1
1   RIGID_AVG   NULL    1
1   RIGID_AVG   NULL    2
1   RIGID_AVG   NULL    3
2   FLEX_AVG    NULL    2
2   FLEX_AVG    NULL    3
2   FLEX_AVG    22.1    1
2   RIGID_AVG   NULL    1
2   RIGID_AVG   NULL    2
2   RIGID_AVG   NULL    3

我在追求:

ID  NAME    FACTOR_VALUE    CLASS
1   FLEX_AVG    NULL    3
1   FLEX_AVG    12.1    2
1   FLEX_AVG    34.4    1
1   RIGID_AVG   NULL    1
1   RIGID_AVG   NULL    2
1   RIGID_AVG   NULL    3
2   FLEX_AVG    NULL    2
2   FLEX_AVG    NULL    3
2   FLEX_AVG    22.1    1
2   RIGID_AVG   NULL    1
2   RIGID_AVG   NULL    2
2   RIGID_AVG   NULL    3

3 个答案:

答案 0 :(得分:4)

id表格中的不同DataPermutations表格交叉加入,为您提供所需的组合,left joinData填充相应的值。

select 
    A.id,
    A.name,
    X.factor_value,
    A.class
from (
  select distinct
      a.*
    , d.id 
  from Permutations A 
    cross join Data D
    ) as A
  left join Data X
    on a.Name = x.Name 
   and a.Class = x.Class
   and a.Id = x.Id

这也可以用更简单的子查询编写:

select 
    D.id,
    A.name,
    X.factor_value,
    A.class
from Permutations A 
  cross join (select distinct id from Data) D
  left join Data X
    on a.Name = x.Name 
   and a.Class = x.Class
   and d.Id = x.Id

rextester演示:http://rextester.com/EJJI30111

返回:

+----+-----------+--------------+-------+
| id |   name    | factor_value | class |
+----+-----------+--------------+-------+
|  1 | FLEX_AVG  | 34,40        |     1 |
|  2 | FLEX_AVG  | 22,10        |     1 |
|  1 | RIGID_AVG | NULL         |     1 |
|  2 | RIGID_AVG | NULL         |     1 |
|  1 | FLEX_AVG  | 12,10        |     2 |
|  2 | FLEX_AVG  | NULL         |     2 |
|  1 | RIGID_AVG | NULL         |     2 |
|  2 | RIGID_AVG | NULL         |     2 |
|  1 | FLEX_AVG  | NULL         |     3 |
|  2 | FLEX_AVG  | NULL         |     3 |
|  1 | RIGID_AVG | NULL         |     3 |
|  2 | RIGID_AVG | NULL         |     3 |
+----+-----------+--------------+-------+

答案 1 :(得分:0)

您需要所有排列,因此排列表应该是第一个。此外,您需要使用相应的数据加入排列,而不是从任何地方加入任何内容,那么为什么ON 1 = 1?

这将有效:

SELECT A.Class,A.Name,X.Id,X.Factor_Value
FROM Permutations A
  JOIN Data X ON X.Class=A.Class and X.Name=A.name

答案 2 :(得分:0)

你想要的和你得到的最大的差别几乎与左和右之间的差异相同 - 字面意思。

SELECT DISTINCT
    A.ID,
    A.NAME,
    X.FACTOR_VALUE,
    A.CLASS
FROM Data X
RIGHT JOIN Permutations A
    ON A.ID = X.ID
    AND A.NAME = X.NAME