查找并插入虚拟行 - OUTER APPLY的可能方案

时间:2013-09-04 12:19:55

标签: sql sql-server

这是我们所得到的情况的模拟:

IF OBJECT_ID('TEMPDB..#People') IS NOT NULL BEGIN DROP TABLE #People END;
CREATE TABLE #People
    (
    Name VARCHAR(100),
    Category VARCHAR(20),
    ID INT
    );
INSERT INTO #People
    values
    ('x','Bronze',1),
    ('y','Bronze',2),
    ('z','Silver',3),
    ('j','Gold',4),
    ('q','Bronze',5),
    ('x','Silver',1);


IF OBJECT_ID('TEMPDB..#Category') IS NOT NULL BEGIN DROP TABLE #Category END;
CREATE TABLE #Category
    (
    Category VARCHAR(100)
    );
INSERT INTO #Category
    values
    ('Gold'),
    ('Silver'),
    ('Bronze');

如果name没有Categoryx没有Gold然后我想创建一行并添加到表#People中,ID为-1。

我现有的解决方案是:

WITH x AS
    (
    SELECT  DISTINCT
            x.Name,
            s.Category
    FROM    #People x
            CROSS JOIN #Category s
    )
INSERT  INTO    #People
SELECT  J.Name,
        J.Category,
        ID = -1
FROM    x J
WHERE   NOT EXISTS
        (
        SELECT  1
        FROM    #People Q
        WHERE   J.Name = Q.Name
                AND J.Category = Q.Category
        );

看到它有效!...:

SELECT *
FROM #People;

我有一种感觉CROSS APPLY可能是一个很好的运算符,以便简化上述内容 - 查找,创建和插入这些行的最简单方法是什么?

1 个答案:

答案 0 :(得分:1)

insert into People(Name, Category, Id)
(
select distinct
  p.Name, 
  c.Category, 
  p.Id 
from 
        people p 
  cross join category c
where
  Concat(p.id, c.Category) not in (select Concat(id, Category) from people)
);

http://www.sqlfiddle.com/#!6/92cd5/14