【问题标题】:how to derive filter condition from table rows如何从表行中导出过滤条件
【发布时间】:2020-04-21 19:29:37
【问题描述】:

如何根据下面给出的行推导出 bteq 中的过滤条件?

表 B:

COLA COLB COLC
1    CODE  AAA
1    DESC  BBB
1    TYPE  CCC

这里有一些代码:

SELECT * FROM TABLE A WHERE CODE IN ('AAA') AND DESC IN ('BBB') AND TYPE IN ('CCC')

【问题讨论】:

  • 添加更多样本数据并指定预期结果。
  • 这里实际存在多少张表?
  • 您似乎正在尝试比较一行中COLBCOLC 的值。如果是这种情况,那么您可以使用 LIKE 运算符或数组比较。 COLC的数据类型是什么?您在伪查询中对IN 的定义是什么?
  • 这似乎是一个使用表 B 生成动态 SQL 的请求,其中包含不同数量的谓词引用任意列名和可能的列值列表。虽然在 BTEQ 中可以做到这一点,但您最好使用一些过程语言(数据库中的存储过程、客户端上的 Python 脚本等)来构建查询。

标签: sql teradata


【解决方案1】:

这里的一种方法是按COLA 聚合,然后为您期望的键/值添加三个断言:

SELECT
    COLA
FROM yourTable
GROUP BY
    COLA
HAVING
    COUNT(CASE WHEN COLB = 'CODE' AND COLC = 'AAA' THEN 1 END) > 0 AND
    COUNT(CASE WHEN COLB = 'DESC' AND COLC = 'BBB' THEN 1 END) > 0 AND
    COUNT(CASE WHEN COLB = 'TYPE' AND COLC = 'CCC' THEN 1 END) > 0;

【讨论】:

  • COLBCOLCB 表中,并且 OP 想要过滤表 A。你只查询一张表,那它应该如何工作?
【解决方案2】:

您可以使用公用表表达式重写查询。

WITH CTE_TableB(ColA, Code, DESC,TYPE) AS
(
SELECT COLA, CASE WHEN COLB = 'Code' THEN COLC ELSE NULL AS Code
           , CASE WHEN COLB = 'DESC' THEN COLC ELSE NULL AS DESC
           , CASE WHEN COLB = 'TYPE' THEN COLC ELSE NULL AS TYPE
FROM TABLEB
)
SELECT *
FROM CTE_TableB
WHERE  CODE IN ('AAA') AND DESC IN ('BBB') AND TYPE IN ('CCC');

或者使用派生表

SELECT *
FROM
(
SELECT COLA, CASE WHEN COLB = 'Code' THEN COLC ELSE NULL AS Code
           , CASE WHEN COLB = 'DESC' THEN COLC ELSE NULL AS DESC
           , CASE WHEN COLB = 'TYPE' THEN COLC ELSE NULL AS TYPE
FROM TABLEB
) AS t
WHERE  CODE IN ('AAA') AND DESC IN ('BBB') AND TYPE IN ('CCC');

【讨论】:

  • COLBCOLCB 表中,并且 OP 想要过滤表 A。你没有对表 A 做任何事情,那么它应该如何工作?
【解决方案3】:

要使用表B 中的值过滤表A,并假设表B 中没有值的列意味着在该列上未过滤,您可以这样做:

SELECT *
  FROM A
 WHERE ( NOT EXISTS ( SELECT * FROM B WHERE B.COLB = 'CODE' )
      OR A.CODE IN ( SELECT B.COLC FROM B WHERE B.COLB = 'CODE' ) )
   AND ( NOT EXISTS ( SELECT * FROM B WHERE B.COLB = 'DESC' )
      OR A.DESC IN ( SELECT B.COLC FROM B WHERE B.COLB = 'DESC' ) )
   AND ( NOT EXISTS ( SELECT * FROM B WHERE B.COLB = 'TYPE' )
      OR A.TYPE IN ( SELECT B.COLC FROM B WHERE B.COLB = 'TYPE' ) )

【讨论】:

  • 我认为“A”和“B”表之间没有任何关系,并认为这只是一个错字,并且只有一个表。
  • @TimBiegeleisen 关系是B.COLB 包含表A 中列的名称,而B.COLC 包含该表中要匹配的值@987654328 @ 柱子。 猜测B.COLA的整数值代表A表。这是这个问题对我有意义的唯一方式,但它确实很有意义。
【解决方案4】:

您可以为此使用inexists

select a.*
from a 
where a.code in (select b.colc from b where b.colb = 'CODE') and
      a.desc in (select b.colc from b where b.colb = 'DESC') and
      a.type in (select b.colc from b where b.colb = 'TYPE');

需要注意的是,这假定表 b 中的每个值至少有一个。

您可以处理缺失值。一种方法使用额外的子查询:

select a.*
from a 
where (a.code in (select b.colc from b where b.colb = 'CODE') or
       not exists (select 1 from b where b.colb = 'CODE')
      ) and
      (a.desc in (select b.colc from b where b.colb = 'DESC') or
       not exists (select 1 from b where b.colb = 'DESC')
      ) and
      (a.type in (select b.colc from b where b.colb = 'TYPE') or
       not exists (select 1 from b where b.colb = 'TYPE')
      );

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2020-02-23
    • 1970-01-01
    • 2022-08-05
    • 2018-01-23
    • 1970-01-01
    • 2021-06-16
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多