使用 SQL 将缺失值插入 Table
Insert Missing Values Into Table Using SQL
Objective:我需要通过 [PropertyId] 分组为每列的值矩阵完全填充 table。几个 [PropertyId] 具有每列的所有必要值 (Table 1),但是,许多缺少一些值 (Table 2)。此外,并非每个 [PropertyId] 都需要这些值,因为它们具有完全不同的区域值。因此,我需要确定哪些 [PropertyId] 既需要填充值又没有所有必要的值。
例子:
Table 1. 每个确定的 [PropertyId] 分组应该有 23 个不同的记录用于这四个列 [ReportingVolumeSettingId]、[SpeciesGroupInventoryID]、[CropCategoryID]、[SortOrder]。
Table 2. 这是缺少值组合的 PropertyID 示例,因为它只有 22 条记录:
这两个示例结果都是从同一个 table [ReportingVolume] 查询的。我什至未能成功确定每个 [PropertyID] 缺少哪些记录组合。我想识别每个缺失的记录组合,然后将该记录组合插入 [ReportingVolume] table.
要解决的问题 -- 下面的 SQL 代码是我尝试 1. 确定正确的值列表; 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 的 table?
我正在使用 SQL SMSS v15.
非常感谢。
我无权访问您的数据,因此我无法提供特定于您的环境的示例,但我可以使用 SQL 服务器的 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)和一些虚拟数据来检查它们。此初始 SELECT 显示指定 @PropertyID 的当前结果集:
+------------+------------+
| PropertyId | RequiredId |
+------------+------------+
| 1 | 1 |
| 1 | 2 |
| 1 | 3 |
+------------+------------+
您可以看到缺少 required_id 值 4 和 5当前 属性。接下来,我们可以使用 EXCEPT
运算符比较 @Required 与 @Data 和 INSERT
任何缺少的必需值,然后 return 更正后的结果集。
-- 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 运算符,然后是要验证的当前行。这个很重要。 EXCEPT 是说向我显示 @Required 中不在 @Data 中的行——这允许将任何缺失的必需值插入到 @Data 中。
我知道这个例子并不代表您现有的 23 行数据要求,但希望它能帮助您找到满足您需求的解决方案。您可以阅读有关 EXCEPT
运算符 here.
的更多信息
这是完整的 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
Objective:我需要通过 [PropertyId] 分组为每列的值矩阵完全填充 table。几个 [PropertyId] 具有每列的所有必要值 (Table 1),但是,许多缺少一些值 (Table 2)。此外,并非每个 [PropertyId] 都需要这些值,因为它们具有完全不同的区域值。因此,我需要确定哪些 [PropertyId] 既需要填充值又没有所有必要的值。
例子: Table 1. 每个确定的 [PropertyId] 分组应该有 23 个不同的记录用于这四个列 [ReportingVolumeSettingId]、[SpeciesGroupInventoryID]、[CropCategoryID]、[SortOrder]。
Table 2. 这是缺少值组合的 PropertyID 示例,因为它只有 22 条记录:
这两个示例结果都是从同一个 table [ReportingVolume] 查询的。我什至未能成功确定每个 [PropertyID] 缺少哪些记录组合。我想识别每个缺失的记录组合,然后将该记录组合插入 [ReportingVolume] table.
要解决的问题 -- 下面的 SQL 代码是我尝试 1. 确定正确的值列表; 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 的 table?
我正在使用 SQL SMSS v15.
非常感谢。
我无权访问您的数据,因此我无法提供特定于您的环境的示例,但我可以使用 SQL 服务器的 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)和一些虚拟数据来检查它们。此初始 SELECT 显示指定 @PropertyID 的当前结果集:
+------------+------------+
| PropertyId | RequiredId |
+------------+------------+
| 1 | 1 |
| 1 | 2 |
| 1 | 3 |
+------------+------------+
您可以看到缺少 required_id 值 4 和 5当前 属性。接下来,我们可以使用 EXCEPT
运算符比较 @Required 与 @Data 和 INSERT
任何缺少的必需值,然后 return 更正后的结果集。
-- 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 运算符,然后是要验证的当前行。这个很重要。 EXCEPT 是说向我显示 @Required 中不在 @Data 中的行——这允许将任何缺失的必需值插入到 @Data 中。
我知道这个例子并不代表您现有的 23 行数据要求,但希望它能帮助您找到满足您需求的解决方案。您可以阅读有关 EXCEPT
运算符 here.
这是完整的 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