在 Firebird 中使用多个 NOT IN

Using multiple NOT IN in Firebird

Table: 分享数

ShareTypeCode ShareNumber StartDate LastDate
stc1 snA 2021-01-01 2021-01-31
stc1 sn001 2021-01-01 null
stc1 sn002 2021-01-01 null
stc1 sn003 2021-01-01 null
stc1 sn004 2021-01-01 null
stc1 sn005 2021-01-01 null
stc2 sn001 2021-01-01 null
stc2 sn002 2021-01-01 null
stc2 sn003 2021-01-01 null
stc2 sn004 2021-01-01 null
stc2 sn005 2021-01-01 null

Table:股权

ShareHolderCode ShareTypeCode ShareNumber StartDate LastDate
shc1 stc1 sn001 2021-01-01 2021-1-31
shc1 stc1 sn002 2021-01-01 null

Table: 分享数

ShareTypeCode stc1 与 ShareNumber snA 到 sn005 被取消。 ShareTypeCode stc1 和 ShareNumber sn001 到 sn005 是有效的共享号。 ShareTypeCode stc2 with ShareNumber sn001 to sn005 是有效的共享号。

Table:股权

ShareTypeCode stc1 ShareNumber sn001 被卖给了一个股东,最后股东退出了,公司又买回来了。 ShareTypeCode stc1 与 ShareNumber sn002 已出售给股东,股东仍持有。

SQL 有效份额:

select "ShareTypeCode", "ShareNumber" 
from "ShareHolding" 
where "LastDate" is null

如果投资者想购买股票,ShareTypeCode stc1 和 ShareNumber sn002,您能否帮助更正以下 SQL 陈述?

SELECT "SN"."ShareTypeCode", "SN"."ShareNumber" 
FROM "ShareNumber" "SN" 
WHERE "SN"."LastDate" is null 
and "SN"."ShareTypeCode" = 'stc1' 
and "SN"."ShareNumber" = 'sn002' 
and "SN"."ShareTypeCode", "SN"."ShareNumber" not in ( select "SH"."ShareTypeCode", "SH"."ShareNumber" from "ShareHolding" "SH" where "SH"."LastDate" is null)
If found
   ShareTypeCode stc1 with ShareNumber sn002 is available for sale.
End If

Firebird 不支持行值,如果支持,SQL 标准语法要求将它们括在括号中。也就是说,您的查询将是 ("SN.ShareTypeCode", "SN.ShareNumber") not in (...)。但是,由于 Firebird 不支持此功能,因此这是一个有争议的问题。

相反,您需要使用 NOT EXISTS:

的相关子查询
SELECT "SN"."ShareTypeCode", "SN"."ShareNumber" 
FROM "ShareNumber" "SN" 
WHERE "SN"."LastDate" is null 
and "SN"."ShareTypeCode" = 'stc1' 
and "SN"."ShareNumber" = 'sn002' 
and not exists (
  select *
  from "ShareHolding" "SH" 
  where "SH"."LastDate" is null
  and "SN"."ShareTypeCode" = "SH"."ShareTypeCode"
  and "SN"."ShareNumber" = "SH"."ShareNumber"
)