【问题标题】:SQL query to filter the records based on a value across columnsSQL 查询基于跨列的值过滤记录
【发布时间】:2022-11-03 18:06:11
【问题描述】:

我的场景是过滤掉在任何列中具有值“RED”的记录

例如:表名:颜色

ID   Col1     Col2   Col3
1    BLUE     RED      YELLOW
2    RED      GREEN    PINK
3    YELLOW    BLACK    BLUE
4    WHITE     GREY      RED

我必须检索记录 1、2、4,因为它们的至少一列中有 RED。我尝试了下面的 3 列表查询

Select * from Colors
where Col1= 'RED' or Col2= 'RED' or Col3 ='RED'

但是,如果我在表颜色中有 100 多列怎么办。有没有其他方法可以过滤这种情况?

【问题讨论】:

  • 也许 ...WHERE 'red' IN (col1,col2,col3,...,col100)?
  • 您有设计问题,尝试将您的数据转换为第三范式,这些问题将自行解决。

标签: sql oracle


【解决方案1】:

如果我们假设您要搜索类型为 VARCHAR2 的所有列,您可以在名为“Colors”的“表”中找到包含“Red”的所有行的 ID,如下所示:

DECLARE
    type found_array_t is varray(10000) of varchar2(100);
    found_array  found_array_t;
-- Type the owner of the tables you are looking at
  v_owner VARCHAR2(255) :='owner';

-- Type the data type you are look at (in CAPITAL)
-- VARCHAR2, NUMBER, etc.
  v_data_type VARCHAR2(255) :='VARCHAR2';

-- Type the string you are looking at
  v_search_string VARCHAR2(4000) :='RED';

BEGIN
  FOR t IN (SELECT table_name, column_name FROM all_tab_cols where owner=v_owner and (data_type = v_data_type or column_name='ID') and table_name = 'Colors') 
  LOOP
    IF t.column_name != 'ID' THEN
        EXECUTE IMMEDIATE 
        'SELECT ID FROM '||t.table_name||' WHERE '||t.column_name||' = :1'
        BULK collect INTO found_array
        USING v_search_string;
        FOR j IN 1..found_array.count
        LOOP
        dbms_output.put_line( t.table_name ||' '||found_array(j) );
        END LOOP;
    END IF;
  END LOOP;
END;

【讨论】:

    【解决方案2】:

    好的,您要查询一个包含 +100 列的表。试试这个:

    CL SCR
    
    SET SERVEROUTPUT ON
    
    DECLARE
        where_str   VARCHAR2(3000);
        str         VARCHAR2(3000);
        col_list    VARCHAR2(3000);
    BEGIN
        where_str := 'SELECT LISTAGG(column_name,'' = ''''RED'''' OR '') WITHIN GROUP (ORDER BY column_name) || '' = ''''RED'''' '' FROM all_tab_cols
                      WHERE OWNER=''VARSA'' AND table_name=''COLOR'' AND  data_type=''VARCHAR2''';
        EXECUTE IMMEDIATE where_str INTO col_list;
        str := 'SELECT * FROM COLOR WHERE ' || col_list;
        dbms_output.put_line(str);
    END;
    

    这个块给你一个这样的查询:

    SELECT * FROM COLOR WHERE COL1 = 'RED' OR COL2 = 'RED' OR COL3 = 'RED';
    

    然后您可以运行查询并查看结果。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2020-01-29
      • 1970-01-01
      相关资源
      最近更新 更多