为什么 'NOT IN' 运算符不为没有任何值的列获取记录?

Why 'NOT IN' operator not fetching records for the columns which is not having any value?

我有一个 table 的列名为 CORP_SERIOUS,该列的值可以是 1 或 2 或为空。当我使用 NOT IN 运算符搜索 unknown values 记录意味着 empty 字段时,我得到 计数为零

为什么下面的查询 没有获取 没有 vm.CORP_SERIOUS NOT IN('1','2') 的字段的记录?

这是查询:

SELECT COUNT(*)
FROM
  ( SELECT DISTINCT vm.vaer_no vaer,
    vm.vaer_no_version version,
    vm.priority priority,
    vm.case_reported_in reportedIn,
    vsr.originalreceivedate initialRcvDate,
    vsr.mostrecentinfodate latestRcvDate,
    vsr.primarysourcecountry reportingCountry,
    vsr.occurcountry occurCountry,
    vsrd.primary_source_full_name reporterFullName,
    vsrd.sender_full_name senderFullName,
    vm.record_id recordId,
    vm.notes_flag notesFlag,
    vm.dmi_product product,
    vmf.VAERS_LINKED,
    vm.VAER_STATUS status,
    vm.company_unit_name companyunit,
    FIND_WF_ACTIVITY(vm.record_id,JBPM_PROCESS_INST_ID),
    vmf.CORRESPONDENCE_FLAG corresFlag,
    vmf.READ_UNREAD_CORRESPONDENCE readUnreadCorresp,
    vm.vaer_mode vmode,
    srcDoc.doc_name,
    vsr.seriousnessdecision serious,
    vm.reportduedate reportduedate,
    vm.MANUALLY_LOCKED,
    vm.LOCKED_BY,
    vm.LOCKED_REASON,
    vm.LOCKED_DATE,
    vm.vaer_delete,
    vm.vaer_nullify nullify,
    vm.archived,
    vm.COMPLETION_FLAG,
    vm.ASSIGNED_USER_GROUP,
    COALESCE(vsrd.TEEATESPECIESDECODE,vsrd.SPECIESDECODE,vsrd.OTHERSPECIES,vsrd.TREATEDSPECIES),
    COALESCE(vsrd.ANIMAL_BREEDDECODE,vsrd.TREATED_BREEDDECODE,vsrd.ANIMAL_BREED,vsrd.TREATED_BREED),
    vm.APPROVED_VAER,
    vm.SUBSTANCE_ADDED,
    vm.MULTIPLEBREEDADDED,
    msg_q.MDN_DATE,
    vm.CASE_SOURCE,
    vm.MESSAGENUMB,
    vsr.NULLIFICATIONREASON,
    vm.CREATED_BY,
    vm.ASSESSMENT_SOURCE,
    vm.ASSESSMENT_CLASSIFICATION,
    vm.DMI_VEDDRA_TERM,
    vsr.CASEREGISTRATIONTYPE,
    vm.AUTHORIZATIONCOMPANY,
    vm.E2B_DMI_PRODUCT brandname,
    vm.E2B_SUBSTANCE_ADDED e2bSubstanceAdded,
    vm.ACCOUNT account,
    ACK.record_id ack_recId ,
    vm.SUBMITTED_DELAY
  FROM agvet_vae_info vm,
    agvet_vae_safetyreport vsr,
    agvet_vae_safetyreport_detail vsrd,
    AGVET_VAE_SOURCE_DOC srcDoc,
    AGVET_VAE_FLAGS vmf,
    E2B_MESSAGE_QUEUE msg_q,
    E2B_MESSAGE_ACK ACK
  WHERE vm.fk_avsr_rec_id      = vsr.record_id
  AND vsr.fk_avsrd_rec_id      = vsrd.record_id
  AND srcdoc.record_id(+)      = vm.fk_vet_source_doc_rec_id
  AND vm.IMPORT_FLAG          <> 1
  AND (vm.DRAFT_SUBMIT_FLAG    = 0
  OR vm.DRAFT_SUBMIT_FLAG      = 2)
  AND vm.VAER_NO               = vmf.VAER_NO(+)
  AND vm.E2B_MESSAGE_LIST_TYPE<>01
  AND vm.MESSAGENUMB           = msg_q.MESSAGE_NUMBER(+)
  AND vm.MESSAGENUMB           = ACK.MESSAGE_NUMBER(+)
  AND (vm.assigned_to          = 48626
  OR vm.assigned_to           IS NULL
  OR vm.assigned_to            = 320538
  OR vm.assigned_to            = 320529
  OR vm.assigned_to            = 406699)
  AND EXISTS
    (SELECT *
    FROM jbpm_token jt
    WHERE jt.node_             IN ( 135,140,146,137,132,129,127,148,144 )
    AND jt.processinstance_     = vm.jbpm_process_inst_id
    OR vm.jbpm_process_inst_id IS NULL
    )
  AND ( fn_access_vet_products(48658,vm.RECORD_ID, vm.CASE_REPORTED_IN)=1)
  AND (vm.PRIORITY                                                    IN ( 02 )
  OR vm.PRIORITY                                                      IS NULL)
  AND ( upper(vm.CORP_SERIOUS) NOT                                    IN ('1','2') )
  AND vm.ARCHIVED                                                      = 0
  AND vm.vaer_nullify                                                  = 0
  AND vm.vaer_delete                                                   = 0
  )

你可以试试这个查询

convert(varchar(50),vm.CORP_SERIOUS) NOT IN('1','2')

值NULL表示未知。

WHERE vm.CORP_SERIOUS IN('1','2')
  • “1”为真
  • 对于“3”是假的
  • 对于 NULL
  • 是 NULL

WHERE vm.CORP_SERIOUS NOT IN('1','2')
  • 不正确,因此“1”为错误
  • 不是 FALSE,因此对于“3”是 TRUE
  • 不是 NULL,对于 NULL
  • 又是 NULL

由于 NULL 表示未知,我们不知道该值(我们不知道)是否在给定的集合中。所以答案是"I don't know",无论我们问值是否在列表中或值是否不在列表中。

假设我们不知道约翰的 phone 号码,我给你看一些号码,然后问你约翰的号码是否在其中。你不能说是,你不能说不是,你只能说也许。与 DBMS 相同。它不能告诉你 TRUE 或 FALSE,它只能告诉你 NULL。现在 WHERE 子句的工作方式如下:查询 returns 给定条件为 TRUE 的所有记录。 NULL 不为 TRUE,因此不返回记录。

(即使 NULL 本身在列表中,我们也不知道集合中的未知值是否与记录中的未知值相同。WHERE 子句仍然会导致 NULL。它会使但是 '3' 的区别:WHERE vm.CORP_SERIOUS NOT IN('1','2', null) 也会突然导致 NULL,因为集合中的未知值可能是也可能不是 '3'。)

你可以问:给我所有未知值加上列表中的值。

WHERE vm.CORP_SERIOUS IS NULL OR vm.CORP_SERIOUS NOT IN('1','2')

或者您可以问:

WHERE NVL(vm.CORP_SERIOUS, 'TREAT AS NOT IN THE LIST') NOT IN('1','2')

(嗯,当然字符串 'TREAT AS NOT IN THE LIST' 不能在列表中:-)