使用SQL将缺少的值插入表中

使用SQL将缺少的值插入表中,sql,sql-server,sql-insert,Sql,Sql Server,Sql Insert,目标:我需要通过[PropertyId]分组为每列完全填充一个值矩阵。一些[PropertyId]具有表1中每列所需的所有值,但是,许多[PropertyId]缺少表2中的一些值。此外,并非每个[PropertyId]都需要这些值,因为它们具有完全不同的区域值。因此,我需要确定哪些[PropertyId]既需要填充值,又没有所有必要的值 示例: 表1。每个已识别的[PropertyId]分组在这四列[ReportingVolumeSettingId]、[SpeciesGroupInventory

目标:我需要通过[PropertyId]分组为每列完全填充一个值矩阵。一些[PropertyId]具有表1中每列所需的所有值,但是,许多[PropertyId]缺少表2中的一些值。此外,并非每个[PropertyId]都需要这些值,因为它们具有完全不同的区域值。因此,我需要确定哪些[PropertyId]既需要填充值,又没有所有必要的值

示例: 表1。每个已识别的[PropertyId]分组在这四列[ReportingVolumeSettingId]、[SpeciesGroupInventoryID]、[CropCategoryID]、[SortOrder]中应有23条不同的记录

表2。以下是缺少值组合的PropertyID示例,因为它只有22条记录:

这两个示例结果都是从同一个表[ReportingVolume]中查询的。我甚至没有成功地确定每个[PropertyID]缺少哪个记录组合。我想识别每个缺失的记录组合,然后将该记录组合插入[ReportingVolume]表中

要解决的问题-下面的SQL代码是我试图解决的问题。确定正确的值列表;2.确定哪些属性应具有匹配值;3.确定哪些属性缺少值;4.确定每个属性缺少的值

    ;with CORRECT_LIST as
(
select 
SpeciesGroupInventoryName, SpeciesGroupInventoryId, CropCategoryName,CropCategoryID, UnitOfMeasure, SortOrder
--*
from [GIS].[RST].[vPropertyDefaultTimberProductAndUnitOfMeasure]
where PropertyId in (1)
)
,
property_list as
(
select distinct rvs.propertyid as Volume_Property, pd.PropertyName, pd.PropertyId from RMS.GIS.ReportingVolumeSetting rvs
right outer JOIN RMS.GIS.PropertyDetail AS pd ON rvs.PropertyId = pd.PropertyId 
left outer  JOIN RMS.GIS.SpeciesGroupInventory AS sgi ON rvs.SpeciesGroupInventoryId = sgi.SpeciesGroupInventoryId
where sgi.SpeciesGroupInventoryId in (1,2,3)
or pd.PropertyId = 171
)
, Partial_LISTS as
(
select Count(distinct ReportingVolumeSettingId) as CNT_REPORT, pd.PropertyName, pd.PropertyId
from [GIS].[ReportingVolumeSetting] rvs
right outer JOIN property_list AS pd ON rvs.PropertyId = pd.PropertyId 
group by pd.propertyId, pd.PropertyName
)
, Add_Props as
(
select propertyName, propertyId, SUM(CNT_REPORT) as CNT_RECORDS from Partial_LISTS
where CNT_REPORT < 23
group by propertyName, propertyId
)
, RVS_RECORDS_PROPS as
(
select addProps.PropertyName, rvs.* from [GIS].[ReportingVolumeSetting] rvs
join Add_Props addProps on addprops.PropertyId = rvs.PropertyID
where rvs.PropertyId in (select PropertyId from Add_Props)
)
select rp.PropertyName, cl.*, rp.SpeciesGroupInventoryId from correct_list cl
left outer join RVS_Records_Props rp 
    on rp.SpeciesGroupInventoryId = cl.SpeciesGroupInventoryId
    and rp.CropCategoryId = cl.CropCategoryID
    and rp.SortOrder = cl.SortOrder
Order by rp.PropertyName
如何修改代码或创建一个新的代码块来标识缺少的值,并将它们按PropertyId插入表中

我使用的是SQLSMSSV15


非常感谢。

我无法访问您的数据,因此我无法提供特定于您环境的示例,但我可以使用SQL Server的EXCEPT运算符为您提供一个简单的示例

在SSMS中运行以下示例:

-- Create a list of required values.
DECLARE @Required TABLE ( required_id INT, required_val VARCHAR(50) );
INSERT INTO @Required ( required_id, required_val ) VALUES
    ( 1, 'Required value 1.' ), ( 2, 'Required value 2.' ), ( 3, 'Required value 3.' ), ( 4, 'Required value 4.' ), ( 5, 'Required value 5.' );

-- Create some sample data to compare against.
DECLARE @Data TABLE ( PropertyId INT, RequiredId INT );
INSERT INTO @Data ( PropertyId, RequiredId ) VALUES
    ( 1, 1 ), ( 1, 2 ), ( 1, 3 ), ( 2, 1 ), ( 2, 2 ), ( 2, 4 ), ( 2, 5 );

-- Set a property id value to query.
DECLARE @PropertyId INT = 1;

-- Preview @Data's rows for the specified @PropertyId.
SELECT * FROM @Data WHERE PropertyId = @PropertyId ORDER BY PropertyId, RequiredId;
在这一点上,我已经创建了一个所需值的列表(required_id 1到5)和一些虚拟数据来检查它们。此初始选择显示指定@PropertyID的当前结果集:

+------------+------------+
| PropertyId | RequiredId |
+------------+------------+
|          1 |          1 |
|          1 |          2 |
|          1 |          3 |
+------------+------------+
您可以看到当前属性缺少必需的_id值4和5。接下来,我们可以将@Required与@Data进行比较,并使用EXCEPT运算符插入任何缺少的必需值,然后返回更正后的结果集

-- Insert any missing required values for @PropertyId.
INSERT INTO @Data ( PropertyId, RequiredId )
SELECT @PropertyId, required_id FROM @Required
EXCEPT
SELECT PropertyId, RequiredId FROM @Data WHERE PropertyId = @PropertyId;

-- Preview @Data's revised rows for @PropertyId.
SELECT * FROM @Data WHERE PropertyId = @PropertyId ORDER BY PropertyId, RequiredId;
更新后的结果集现在如下所示:

+------------+------------+
| PropertyId | RequiredId |
+------------+------------+
|          1 |          1 |
|          1 |          2 |
|          1 |          3 |
|          1 |          4 |
|          1 |          5 |
+------------+------------+
您可以对@PropertyId=2再次运行此命令,以查看不同的场景

请注意使用EXCEPT的顺序。首先是必需的行,然后是EXCEPT运算符,然后是要验证的当前行。这很重要。除了说“显示@Required中不在@Data中的行”,这允许将任何缺少的必需值插入@Data

我知道这个例子并不代表23行要求的现有数据,但希望它能帮助您找到满足需求的解决方案。您可以阅读有关EXCEPT运算符的更多信息

以下是完整的SSMS示例:

-- Create a list of required values.
DECLARE @Required TABLE ( required_id INT, required_val VARCHAR(50) );
INSERT INTO @Required ( required_id, required_val ) VALUES
    ( 1, 'Required value 1.' ), ( 2, 'Required value 2.' ), ( 3, 'Required value 3.' ), ( 4, 'Required value 4.' ), ( 5, 'Required value 5.' );

-- Create some sample data to compare against.
DECLARE @Data TABLE ( PropertyId INT, RequiredId INT );
INSERT INTO @Data ( PropertyId, RequiredId ) VALUES
    ( 1, 1 ), ( 1, 2 ), ( 1, 3 ), ( 2, 1 ), ( 2, 2 ), ( 2, 4 ), ( 2, 5 );

-- Set a property id value to query.
DECLARE @PropertyId INT = 1;

-- Preview @Data's rows for the specified @PropertyId.
SELECT * FROM @Data WHERE PropertyId = @PropertyId ORDER BY PropertyId, RequiredId;

-- Insert any missing required values for @PropertyId.
INSERT INTO @Data ( PropertyId, RequiredId )
SELECT @PropertyId, required_id FROM @Required
EXCEPT
SELECT PropertyId, RequiredId FROM @Data WHERE PropertyId = @PropertyId;

-- Preview @Data's revised rows for @PropertyId.
SELECT * FROM @Data WHERE PropertyId = @PropertyId ORDER BY PropertyId, RequiredId;

这应该可以识别丢失的条目。您只需在上面添加一个INSERT INTO命令即可。请记住,由于ReportingVolumeSettingId是唯一且未知的,因此此处未介绍它

SELECT * FROM (SELECT DISTINCT PropertyId FROM ReportingVolume) rv
CROSS APPLY 
(
    SELECT DISTINCT SpeciesGroupInventoryId
        , CropCategoryId
        , SortOrder
    FROM ReportingVolume
) x
EXCEPT
SELECT PropertyId, SpeciesGroupInventoryId, CropCategoryId, SortOrder FROM ReportingVolume

假设每个属性ID都有唯一的ReportingVolumeSettingId和相等的SpeciesGroupInventoryID、CropCategoryID和SortOrder值是否正确?如果是这样,如果缺少ReportingVolumeSettingId,您如何知道它?@Luke感谢您指出这一点。我不清楚发布此信息时ReportingVolumeSettingId是否唯一。询问分配问题的DB管理员,没有必要为每个PropertyId复制此列,因为它是PropertyId的唯一列。标准列是另外三个:[SpeciesGroupInventoryID]、[CropCategoryID]、[SortOrder]。