如何从sql条件查询中删除冗余代码

ubof19bj  于 2021-07-26  发布在  Java
关注(0)|答案(2)|浏览(310)

我有以下情况。
我得到了一个表,其中有一些经过验证的,未经验证的记录和(比如说)主验证的记录。edited:在表中,我得到了标准的unique id字段,但是还有一个名为verifiedrecordid的列,它指向表中的其他记录,或者为null。
如果记录的verifiedrecordid=null,则为未验证记录。
如果记录有verifiedrecordid=some\u id,那么这个记录将被一个一个地验证
id=some\u id的记录是主验证记录。
许多已验证的记录可能指向一个已验证的主记录。最后一个只是提供验证数据的验证记录,不能直接访问。
但是还有另一个因素决定记录是否被验证,不仅仅是这个字段,所以验证是由存储过程决定的。因此,如果访问未验证的记录,它将返回其字段。如果访问已验证的记录,它将忽略其字段(id除外),并返回它所指向的已验证主记录(id除外)的字段。
因此,我想创建一个存储过程,通过传递@ids参数从表中提取记录,其中可能包含已验证或未验证记录的ID(但不是主验证记录,因为它们不能直接访问)。我得到了这个:

DECLARE @verifiedMasterRecordsIds [dbo].[Ints]
INSERT INTO @verifiedMasterRecordsIds 
EXEC sp_getVerifiedMasterRecordsIds

SELECT record.ID, 
    CASE 
        WHEN record.ID IN (SELECT ID FROM @verifiedMasterRecordsIds) 
        THEN verRecord.Field1
        ELSE record.Field1
    END AS Field1,
    CASE 
        WHEN record.ID IN (SELECT ID FROM @verifiedMasterRecordsIds) 
        THEN verRecord.Field2
        ELSE record.Field2
    END as Field2,
    CASE 
        WHEN record.ID IN (SELECT ID FROM @verifiedMasterRecordsIds) 
        THEN verRecord.Field3
        ELSE record.Field3
    END as Field3,
    CASE 
        WHEN record.ID IN (SELECT ID FROM @verifiedMasterRecordsIds) 
        THEN verRecord.Field4
        ELSE record.Field4
    END AS Field4
INTO #TempRecords
FROM Records as record
LEFT JOIN Records as verRecord ON record.VerifiedRecordID=verRecord.ID

WHERE record.ID IN (SELECT ID FROM @ids)

我最关心的是每个select条件中的冗余代码(select id from@verifiedmasterrecordsids)。如何重构以避免冗余?另外,如果有更好的方法用这个逻辑从这个表中提取数据,我很乐意看到。

hi3rlvi2

hi3rlvi21#

此代码仅返回@ids变量中包含的记录。并选择依赖@verifiedmasterrecordsids变量中现有记录的字段。请写下我是否正确理解你

DECLARE @verifiedMasterRecordsIds [dbo].[Ints]
INSERT INTO @verifiedMasterRecordsIds 
EXEC sp_getVerifiedMasterRecordsIds
;

SELECT record.ID, verRecord.Field1, verRecord.Field2, verRecord.Field3, verRecord.Field4
FROM Records as record
LEFT JOIN Records as verRecord ON record.VerifiedRecordID=verRecord.ID
WHERE record.ID IN (SELECT ID FROM @ids) 
and record.ID IN (SELECT ID FROM @verifiedMasterRecordsIds)

union 

SELECT ID, Field1, Field2, Field3, Field4
FROM Records as record
WHERE ID IN (SELECT ID FROM @ids) 
and ID NOT IN (SELECT ID FROM @verifiedMasterRecordsIds);
vnzz0bqm

vnzz0bqm2#

我发现这个逻辑有点难以用例子来解释——所有这些ID列表,不太清楚要从一个表或另一个表中选择真正需要匹配的是哪一个。
也就是说,如果取消对值的IVOT并将表逻辑移到 FROM 条款。这可能会满足您的要求:

SELECT r.ID, v.which,
       COALESCE(v.verified_field, r._recordfield)
INTO #TempRecords
FROM Records r LEFT JOIN
     @verifiedMasterRecordsIds vmr
     ON vmr.id = r.id LEFT JOIN
     Records vr
     ON vr.ID = r.VerifiedRecordID AND vmr.id IS NOT NULL 
     (VALUES ('Field1', r.Field1, vr.Field1),
             ('Field2', r.Field2, vr.Field2),
             ('Field3', r.Field3, vr.Field3),
             ('Field4', r.Field4, vr.Field4)
     ) v(which, record_field, verified_field)
WHERE r.ID IN (SELECT i.ID FROM @ids i) ;

当然,你可以重新输入数据。
实际上,也许你只是想把条件转移到 FROM 条款——无需取消激励:

SELECT r.ID, v.which,
       (CASE WHEN vrm.id IS NOT NULL THEN vr.Field1 ELSE r.Field1 END),
       (CASE WHEN vrm.id IS NOT NULL THEN vr.Field2 ELSE r.Field2 END),
       (CASE WHEN vrm.id IS NOT NULL THEN vr.Field3 ELSE r.Field3 END),
       (CASE WHEN vrm.id IS NOT NULL THEN vr.Field4 ELSE r.Field4 END)
INTO #TempRecords
FROM Records r LEFT JOIN
     @verifiedMasterRecordsIds vmr
     ON vmr.id = r.id LEFT JOIN
     Records vr
     ON vr.ID = r.VerifiedRecordID  
WHERE r.ID IN (SELECT i.ID FROM @ids i) ;

相关问题