将选择结果存储在变量中并在where条件下使用

时间:2019-07-09 20:59:15

标签: sql firebird

A有3个SQL查询,我使用union进行了组合。 前两个查询返回唯一的订单ID,但第三个查询从前两个查询中重复订单ID。我需要在查询3中排除那些结果。

示例:

QUERY 1:
SELECT DISTINCT
ORDER_ID,
PRODUCT
FROM
ORDERS
WHEN TYPE=A

查询1个样本数据{12121212,13131313}

QUERY 2:
SELECT DISTINCT
ORDER_ID,
PRODUCT,
FROM
ORDERS
WHEN CATEGORY=X

查询2个样本数据{14141414,15151515}

QUERY 3:
SELECT DISTINCT
ORDER_ID,
PRODUCT
FROM    
ORDERS
WHEN TYPE=C

查询3个样本数据{17171717,12121212,14141414}

因此查询3重复查询1和2的数据。实际数据要大得多。我要使用的是使用前2个查询的结果从query3中排除

query1
union
query2
union
SELECT DISTINCT
ORDER_ID,
PRODUCT
FROM    
ORDERS
WHEN TYPE=C
AND
ORDER_ID NOT IN (Variable1=ORDER_ID IN QUERY1,Variable2=ORDER_ID IN QUERY2)

所需数据{12121212,13131313,14141414,15151515,16161616,17171717}

如何存储在where条件中使用的变量?

感谢任何帮助

2 个答案:

答案 0 :(得分:0)

您似乎(但是很难确定)很难进行分层数据收集,是否从第一个可用数据源(从优先级列表中选择)中选择了数据,有了数据,接下来的数据源将会得到忽略。

我认为最好的是制作一个拥有所有内容的持久表:

  

ORDER_ID,PRODUCT,Source_Priority

这样的表将跟踪所有表中的最新数据(例如,通过AFTER UPADTE OR INSERT OR DELETE上的ORDERS触发器和其他来源),然后将您的查询重新格式化为”查询新表,获取具有“每个ORDER_ID值最大的Source_Priority”的行” ,该行被多次询问,并通过Firebird 2中的一个JOIN或Firebird 3中的Window Functions进行解决。

如果您不想拥有专用的持久化优先级表,则可以使用

  1. 全局临时表进行排序 https://firebirdsql.org/file/documentation/reference_manuals/fblangref25-en/html/fblangref25-ddl-tbl.html#fblangref25-ddl-tbl-gtt
  2. MERGE命令进行条件插入(在清除表之前) https://firebirdsql.org/file/documentation/reference_manuals/fblangref25-en/html/fblangref25-dml-merge.html
  3. SELECT从准备的GTT中读取数据

如果您要假装这是一个查询,而不是2 + N,则可以将其隐藏在其中

  1. 名为Stored Procedure或匿名EXECUTE BLOCK https://firebirdsql.org/file/documentation/reference_manuals/fblangref25-en/html/fblangref25-dml-execblock.html

类似的东西:

Create GLOBAL TEMPORARY TABLE TMP_ORDERS
( ORDER_ID integer PRIMARY KEY,
  PRODUCT VarChar(10) );

然后使用此序列替换“一个真实查询”(如果需要,可以隐藏在执行块内)

DELETE FROM TMP_ORDERS;


INSERT INTO TMP_ORDERS
SELECT DISTINCT
ORDER_ID,
PRODUCT
FROM
ORDERS
WHEN TYPE=A;

MERGE INTO TMP_ORDERS as Dest
USING (
  SELECT DISTINCT
  ORDER_ID,
  PRODUCT,
  FROM
  ORDERS
  WHEN CATEGORY=X
) as Src
WHEN NOT MATCHED THEN
  INSERT(Dest.ORDER_ID, Dest.PRODUCT) VALUES(Src.ORDER_ID, Src.PRODUCT);

MERGE INTO TMP_ORDERS as Dest
USING (
  SELECT DISTINCT
  ORDER_ID,
  PRODUCT,
  FROM
  ORDERS
  WHEN TYPE=C) as Src
WHEN NOT MATCHED THEN
  INSERT(Dest.ORDER_ID, Dest.PRODUCT) VALUES(Src.ORDER_ID, Src.PRODUCT);

SELECT * FROM TMP_ORDERS;

P.S。但是为什么您的部分查询甚至包含DISTINCT?首先,ORDER_ID已经不是您的primary key了,那是永远不会与众不同的吗?

答案 1 :(得分:0)

您可以尝试

select * from
 (SELECT DISTINCT
  ORDER_ID,
  PRODUCT
  FROM
  ORDERS
  where TYPE='A') as q1,
 (SELECT DISTINCT
  ORDER_ID,
  PRODUCT
  FROM
  ORDERS
  WHERE CATEGORY='X'
  ) as q2,
 (SELECT DISTINCT
  ORDER_ID,
  PRODUCT
  FROM    
  ORDERS
  where  TYPE='C') as q3
 WHERE q1.order_id=q2.order_id