部分通配符NULL加入SQL 服务器爆出数据方便使用

Partial wildcard NULL join in SQL Server exploding out data for easier use

我有一个问题可以解决,但我怀疑这不是最好的解决方案。 ()

假设你有一些疯狂的人的数据和逻辑:

ImportantNumber   Entity    MappingCode     
---------------------------------------
1                 A         Ted
1                 NULL      Fred
1                 C         Ned

其中 ImportantNumber = 1 映射到 "Ted" 如果 Entity = "A","Ned" 如果 Entity = "C",否则 "Fred" - IE 特定匹配优先。

假设您有 table 个实体,从 A 到 Z。您希望将此 table 展开以包含其他连接和逻辑的所有映射。 (为了娱乐,我有几个这样的专栏....grr...)

我的解决方案是这样的,但是,我确信应该有更有效的方法:

测试数据:

CREATE TABLE #temp
(
    ImportantNumber varchar(1),
    Entity varchar(1),
    Mapping varchar(4)
)

INSERT INTO #temp
VALUES
('1', 'A', 'Ted'),
('1', null, 'Fred'),
('1', 'C', 'Ned')

CREATE TABLE #Entities (Entity varchar(1))
INSERT INTO #Entities VALUES ('A'), ('B'), ('C'), ('D'), ('E') --etc

测试数据示例:

--Use a CTE to create the specific matches
;WITH matches AS
(
SELECT
    t.ImportantNumber,
    e.Entity,
    t.Mapping
FROM
    #Entities e
INNER JOIN
    #temp t
ON
    e.Entity = t.Entity
)
/*
Get the specific matches and UNION them with the NULL entry 
which excludes all Entities in the matches CTE
*/
SELECT
    ImportantNumber,
    Entity,
    Mapping
FROM
    matches
UNION ALL
SELECT
    t.ImportantNumber,
    e.Entity,
    t.Mapping
FROM
    #temp t
LEFT JOIN
    #Entities e
ON
    t.Entity IS NULL -- all Entities will be matched against the NULL column
WHERE
    e.Entity NOT IN (SELECT DISTINCT Entity FROM matches)

请注意,这适用于单个 "ImportantNumber" - 这需要更改为多个的 LEFT JOIN - 但我仍在努力

预期输出应为:

ImportantNumber   Entity    MappingCode     
---------------------------------------
1                 A         Ted
1                 C         Ned
1                 B         Fred
1                 D         Fred
1                 E         Fred
etc for F-Z

这可以是适用于多个 ImportantNumber 的替代解决方案。

CREATE TABLE #temp
(
    ImportantNumber varchar(1),
    Entity varchar(1),
    Mapping varchar(4)
)

INSERT INTO #temp
VALUES
('1', 'A', 'Ted'),
('1', null, 'Fred'),
('1', 'C', 'Ned'),

('2', 'B', 'Ted2'),
('2', null, 'Fred2'),
('2', 'D', 'Ned2')

CREATE TABLE #Entities (Entity varchar(1))
INSERT INTO #Entities VALUES ('A'), ('B'), ('C'), ('D'), ('E') --etc

;WITH Missing AS
(
SELECT
    t.ImportantNumber,
    t.Entity,
    t.Mapping
FROM
    #temp t
WHERE 
    t.Entity IS NULL
)

SELECT
    t.ImportantNumber,
    e.Entity,
    t.Mapping
FROM
    #Entities e
INNER JOIN
    #temp t
ON
    e.Entity = t.Entity
UNION ALL
SELECT
    t.ImportantNumber,
    e.Entity,
    t.Mapping
FROM
    Missing t
CROSS JOIN #Entities e  -- all Entities will be matched with the NULL column    
LEFT JOIN #temp tt ON e.Entity = tt.Entity
      AND t.ImportantNumber = tt.ImportantNumber
WHERE
    tt.Entity IS NULL   -- exclude rows which has matching entity