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

时间:2015-06-29 08:59:02

标签: sql oracle null comparison

我有一个列名为 CORP_SERIOUS 的表格,此列的值可以是 1或2或空。当我搜索未知值记录时,使用 NOT IN 运算符表示字段我得到计数为零

为什么下面的查询没有提取没有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
  )

2 个答案:

答案 0 :(得分:1)

值NULL表示未知。

WHERE vm.CORP_SERIOUS IN('1','2')
    对于'1',
  • 为TRUE 对于'3'
  • 为假
  • 对于NULL
  • 为NULL

并且

WHERE vm.CORP_SERIOUS NOT IN('1','2')
  • 不正确,因此'1'
  • 为假
  • 不为假,因此对于'3'
  • 为真
  • 是NOT NULL,对于NULL
  • 也是NULL

由于NULL意味着未知,我们不知道值(我们不知道)是否在给定集合中。所以答案是“我不知道”,无论我们是否询问该值是否在列表中,或者该值是否在列表中。

想象一下,我们不知道约翰的电话号码,我会告诉你一些数字并问你约翰的号码是否在其中。你不能说是的,你不能说不,你只能说也许。与DBMS相同。它不能告诉你TRUE或FALSE,它只能告诉你NULL。现在,WHERE子句的工作方式如下:查询返回给定条件为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 THE THE LIST'不得出现在列表中: - )

答案 1 :(得分:0)

您可以尝试此查询

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