0

我有一个元数据表,如下所示:

RULE_NAME      COL_NAME   COL_VAL
RULE_1     COL_1         ABC
RULE_1     COL_5         XYZ
RULE_2     COL_2         123
RULE_2     COL_3         A2d5
RULE_2     COL_8         X0IL
RULE_3     COL_1         PQR
RULE_3     COL_7         9789

我需要使用该表中的数据生成 WHERE 子句。WHERE 子句应该是这样的:

WHERE
(COL_1 = 'ABC' AND COL_5 = 'XYZ') --from Rule 1 records
OR
(COL_2 = '123' AND COL_3 = 'A2D5' AND COL_8 = 'X0IL') --From Rule 2 records
OR
(COL_1 = 'PQR' AND COL_7 = '9789') --from Rule 3 records

这可能与普通 SQL(我在 Teradata 上)有关吗?有人可以给我一些关于如何实现这一目标的指示吗?

谢谢。

4

3 回答 3

2

以下将每个子句返回到单独的行:

select oreplace(max(case when seqnum = 1 then clause else '' end) ||
                MAX(case when seqnum = 2 then clause else '' end) ||
                MAX(case when seqnum = 3 then clause else '' end)
               ), ')(', ') and (')
from (select t.*, ROW_NUMBER() over (partition by rule_name order by col_name) as seqnum,
             ('(' || COL_NAME || ' = ' || '''' || col_val || ''')') as clause
      from t
     ) t
group by rule_name

够近了吗?

如果您没有“oreplace”功能,您可以执行以下操作:

select max(case when seqnum = 1 then clause else '' end) ||
       MAX(case when seqnum = 2 then clause else '' end) ||
       MAX(case when seqnum = 3 then clause else '' end) || ' 1=1 OR'
from (select t.*, ROW_NUMBER() over (partition by rule_name order by col_name) as seqnum,
             ('(' || COL_NAME || ' = ' || '''' || col_val || ''') and') as clause
      from t
     ) t
group by rule_name
于 2013-01-17T14:40:46.823 回答
0

您是否尝试过这样的事情(未经测试)?也许你可以提供你想要的结果。

SELECT *
FROM TableName
WHERE 
(
   (COL_Name = 'COL_1' AND COL_Val = 'ABC') 
   OR (COL_Name = 'COL_5' AND COL_Val = 'XYZ')
)
OR 
(
   (COL_Name = 'COL_2' AND COL_Val = '123') 
   OR (COL_Name = 'COL_3' AND COL_Val = 'A2D5') 
   OR (COL_Name = 'COL_8' AND COL_Val = 'X0IL')
) 
OR 
(
   (COL_Name = 'COL_1' AND COL_Val = 'PQR') 
   OR (COL_Name = 'COL_7' AND COL_Val = '9789')
)
于 2013-01-17T14:39:45.747 回答
0

这是基于 scott.emp 表的一般 Oracle 示例。涵盖 EXECUTE IMMEDIATE 和 REF CURSOR:

DECLARE
  v_sql           VARCHAR2(200);
  v_tab_name      VARCHAR2(200):= 'scott.emp';
  v_field_name    VARCHAR2(200):= 'job';
  v_list          VARCHAR2(200):= '''MANAGER'', ''CLERK''';
BEGIN
  v_sql:= 'SELECT * FROM '|| v_tab_name ||' WHERE '||v_field_name ||' IN (:v)';
  EXECUTE IMMEDIATE v_sql USING v_list;
  dbms_output.put_line(v_sql);
END;
/

DECLARE
  emp_cur_rc      SYS_REFCURSOR;
  emp_rec         scott.emp%ROWTYPE;
--
  v_sql           VARCHAR2(200);
  v_tab_name      VARCHAR2(200):= 'scott.emp';
  v_field_name    VARCHAR2(200):= 'job';
  v_list          VARCHAR2(200):= '''MANAGER'', ''CLERK''';
BEGIN
  v_sql:= 'SELECT * FROM '|| v_tab_name ||' WHERE '||v_field_name ||' IN ('||v_list||')';
  EXECUTE IMMEDIATE v_sql;
  dbms_output.put_line('EXECUTE IMMEDIATE example: '||v_sql||chr(13));
--
  OPEN emp_cur_rc FOR v_sql;
  LOOP
    FETCH emp_cur_rc INTO emp_rec;
    EXIT WHEN emp_cur_rc%NOTFOUND;
    dbms_output.put_line('REFCURSOR example: '||emp_rec.empno||chr(9)||emp_rec.ename||chr(9)||emp_rec.job);
  END LOOP;
  CLOSE emp_cur_rc;
END;
/
于 2013-01-17T15:10:37.960 回答