Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/sql/70.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Sql INSERT语句以填充缺少的行_Sql_Sql Server_Tsql - Fatal编程技术网

Sql INSERT语句以填充缺少的行

Sql INSERT语句以填充缺少的行,sql,sql-server,tsql,Sql,Sql Server,Tsql,我有一个客户列表和一些需要与每个客户关联的模板。我试图做的是确保每个缺少模板的客户都能插入模板,但我很难写一份声明来找出哪些客户缺少模板 在下面的数据集中,我有5个客户和3个模板。我怎样才能找到缺失的模板来实现最底层的数据集 Customers CustID, Name C001, John C002, Jack C003, Jim C004, Jill C005, Julie ------------------------------- Templates CustID, Template

我有一个客户列表和一些需要与每个客户关联的模板。我试图做的是确保每个缺少模板的客户都能插入模板,但我很难写一份声明来找出哪些客户缺少模板

在下面的数据集中,我有5个客户和3个模板。我怎样才能找到缺失的模板来实现最底层的数据集

Customers
CustID, Name
C001, John
C002, Jack
C003, Jim
C004, Jill
C005, Julie
-------------------------------

Templates
CustID, TemplateID
C001, T001
C001, T002
C001, T003
C002, T001
C002, T002
C002, T003
C003, T001
C003, T003
C004, T003
-------------------------------

Templates
CustID, TemplateID
C001, T001
C001, T002
C001, T003
C002, T001
C002, T002
C002, T003
C003, T001
C003, T002
C003, T003
C004, T001
C004, T002
C004, T003
C005, T001
C005, T002
C005, T003


----
我不希望看到整个insert语句,但如果您能帮助我找到丢失的行,我们将非常棒。

Join+Except也可以

询问

select TemplateID,CustID from Customers join TemplatesID on 1!=0 
EXCEPT
select TemplateID,CustID from Templates

因此,首先列出所有可能的模板和客户组合

Select Customers.CustId, AllTemplates.TemplateId
From AllTemplates
CROSS JOIN Customers
然后将当前列表与使用左连接的所有可能组合的列表进行比较,如果左连接中出现空值,则发现缺少模板

With AllPossibleCustomerTemplate as (
    Select Customers.CustId, Templates.TemplateId
    From Templates
    CROSS JOIN Customers
)
Select AllPossibleCustomerTemplates.CustId as MissingCustId,
       AllPossibleCustomerTemplates.TemplateId as MissingTemplateId
from AllPossibleCustomerTemplates 
left join ExistingCustomerTemplates ect ON ect.CustId = AllPossibleCustomerTemplates.CustId
                                        AND ect.TemplateId = AllPossibleCustomerTemplates.TemplateId
WHERE ect.CustId is null

请尝试此查询,我的朋友:

with 
t1 as (select distinct TemplateID from Templates),
t2 as (select distinct CustID from Customers),
t3 as (select t2.*,t1.* from t2,t1),
t4 as (select * from t3 where
CustID+TemplateID not in 
(select CustID+TemplateID from Templates))
insert into Templates select * from t4;

这是个好主意。非常感谢。唯一的问题是数据库有数千个客户,因此有数千个模板。执行交叉连接将返回数百万行,因此我不确定这是否是一个实用的解决方案。我不认为您可以从数据库中解脱出来,必须检查每个客户和每个模板以查看缺少的内容。我认为这是值得一试的,因为查询优化者应该知道如何最好地运行查询。如果执行缓慢,您可以添加一些索引,这是下一个问题;)试一试,看看它的性能如何。你只回答了部分问题。你的大部分答案都是DDL,这只会让OP混淆。@sarin,如果你在我提供的真实示例3分钟后发表评论,那是不公平的!我花了几分钟在SQL 2012上进行了尝试。在您的示例中,表名有点混乱。如果
客户
仅包含客户,
模板
应以同样的方式仅包含模板。桥接表(包含指向这两个实体的链接的表)的名称应该不同,可能提及这两个实体,可能是
CustomerTemplates
或类似的内容。这是一个非常好的查询,但我在这里担心的是,最终您会得到所有可能的模板,而不是缺少的模板,因此我需要删除每个模板,并用t4的内容替换它,实际上,t4将有数十万行。不过做得很聪明。但是
t4
返回不在
模板中的行,您可以将它们插入
模板中。我在测试数据库上运行它,其中有2143个客户行,2个模板,其中缺少5个模板,t4返回4286行,而不是5行。
with 
t1 as (select distinct TemplateID from Templates),
t2 as (select distinct CustID from Customers),
t3 as (select t2.*,t1.* from t2,t1),
t4 as (select * from t3 where
CustID+TemplateID not in 
(select CustID+TemplateID from Templates))
insert into Templates select * from t4;
with cte1 as
(
    select
        c.CustID, t.TemplateID
    from
        Customers c
    cross join
        (select distinct TemplateID from Templates) t
),
cte2 as
(
    select
        *
    from
        cte1
    where
        CustID + TemplateID not in(select CustID + TemplateID from Templates)
)

insert into Templates select * from cte2

select * from Templates order by CustID, TemplateID