我有一个元数据表如下:
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上)有关吗?有人可以给我一些关于如何实现这个目标的指示吗?
感谢。
答案 0 :(得分: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
答案 1 :(得分: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')
)
答案 2 :(得分: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;
/