programing

테이블에서 값이 null이 아닌 열을 선택하려면 어떻게 해야 합니까?

bestprogram 2023. 3. 18. 09:28

테이블에서 값이 null이 아닌 열을 선택하려면 어떻게 해야 합니까?

수백 개의 컬럼이 포함된 테이블이 있는데, 그 중 대부분은 늘입니다.값이 포함된 컬럼만 반환되도록 select 문을 원합니다.데이터를 더 잘 분석하는 데 도움이 될 거예요.예를 들어 다음과 같습니다.

tablename에서 (null이 아닌 열)을 선택합니다.

값이 null이 아닌 열을 하나 이상 선택합니다.

할 수 있을까?

다음을 사용합니다.

SELECT *
FROM information_schema.columns
WHERE table_name = 'Table_Name' and is_nullable = 'NO'

Table_Name그에 따라 교체해야 합니다.

통계정보로서 참조해 주세요.이 정보는 도움이 될 수 있습니다.

SQL> exec dbms_stats.gather_table_stats('SCOTT','EMP');

PL/SQL procedure successfully completed.

SQL> select num_rows from all_tables where owner='SCOTT' and table_name='EMP';

  NUM_ROWS
----------
        14

SQL> select column_name,nullable,num_distinct,num_nulls from all_tab_columns
  2  where owner='SCOTT' and table_name='EMP' order by column_id;

COLUMN_NAME                    N NUM_DISTINCT  NUM_NULLS
------------------------------ - ------------ ----------
EMPNO                          N           14          0
ENAME                          Y           14          0
JOB                            Y            5          0
MGR                            Y            6          1
HIREDATE                       Y           13          0
SAL                            Y           12          0
COMM                           Y            4         10
DEPTNO                         Y            3          0

8 rows selected.

예를 들어 NUM_NULLS = NUM_ROWS인지 확인하여 "빈" 열을 식별할 수 있습니다.
참조: ALL_TAB_COLUMNS, ALL_TABLES.

select column_name
from user_tab_columns
where table_name='Table_name' and num_nulls=0;

다음은 null이 아닌 열을 가져오는 간단한 코드입니다.

나는 이것이 하나의 질문으로 이루어질 수 있다고 생각하지 않는다.데이터를 포함하는 열을 먼저 테스트하고 해당 정보를 기반으로 문을 조합하려면 몇 가지 plsql이 필요할 수 있습니다.물론 테이블의 데이터가 변경되면 문을 다시 작성해야 합니다.

declare

   l_table          varchar2(30) := 'YOUR_TABLE';
   l_statement      varchar2(32767);
   l_test_statement varchar2(32767);

   l_contains_value pls_integer;

   -- select column_names from your table
   cursor c is
      select column_name
            ,nullable
        from user_tab_columns
       where table_name = l_table;

begin
   l_statement := 'select ';
   for r in c
   loop
      -- If column is not nullable it will always contain a value
      if r.nullable = 'N'
      then
         -- add column to select list.
         l_statement := l_statement || r.column_name || ',';
      else
         -- check if there is a row that has a value for this column
         begin
            l_test_statement := 'select 1 from dual where exists (select 1 from ' || l_table || ' where ' ||
                                r.column_name || ' is not null)';
            dbms_output.put_line(l_test_statement);
            execute immediate l_test_statement
               into l_contains_value;


            -- Yes, add column to select list
            l_statement := l_statement || r.column_name || ',';
         exception
            when no_data_found then
               null;
         end;

      end if;
   end loop;

   -- create a select statement
   l_statement := substr(l_statement, 1, length(l_statement) - 1) || ' from ' || l_table;

end;
select rtrim (xmlagg (xmlelement (e, column_name || ',')).extract ('//text()'), ',') col
from (select column_name
from user_tab_columns
where table_name='<table_name>' and low_value is not null)

이 블록은 테이블 내의 모든 열을 판별하고 동적 SQL에서 열을 루프하여 늘인지 확인한 후 늘이 아닌 쿼리의 DBMS 출력 쿼리를 구성합니다.

반환된 쿼리를 실행하기만 하면 됩니다.

PK 및 BLOB 열을 제외했습니다.이 방법은 열을 하나씩 처리하는 데 매우 느립니다. 데이터가 너무 빨리 변경될 수 있기 때문에 매우 뜨거운 테이블에는 적합하지 않습니다. 하지만 개발 환경에서 트래픽을 제어하기 때문에 이 방법이 도움이 됩니다.

DECLARE
  l_table_name      VARCHAR2(255) := 'XXXX';
  l_counter         NUMBER;
  l_sql             CLOB;

BEGIN
  FOR r_col IN (SELECT * 
                FROM user_tab_columns tab_col
                WHERE table_name = l_table_name
                AND data_type NOT IN ('BLOB')
                AND column_name NOT IN (SELECT column_name 
                                        FROM user_cons_columns con_col
                                        JOIN user_constraints cons ON con_col.constraint_name = cons.constraint_name AND con_col.table_name = cons.table_name
                                        WHERE con_col.table_name = tab_col.table_name
                                        AND constraint_type = 'P')
                ORDER BY column_id) 
  LOOP

    EXECUTE IMMEDIATE 'SELECT COUNT(1) FROM '||l_table_name||' WHERE '||r_col.column_name||' IS NOT NULL'
    INTO l_counter;
    
    IF l_counter > 0 THEN
      IF  l_sql IS NULL THEN 
        l_sql := r_col.column_name;
      ELSE   
        l_sql :=  l_sql||','||r_col.column_name;
      END IF;
    END IF;
   
  END LOOP;  

  l_sql :=  'SELECT '||l_sql||CHR(10)
         ||'FROM '||l_table_name;
          
  ----------
  DBMS_OUTPUT.put_line(l_sql);  
END;

전체 결과에서 각 행에 대한 종속성을 설정해야 합니다.사실 이건 네가 원하는 게 아니야.한 행에 모든 열의 값이 '0'일 경우 발생하는 결과를 생각해 보십시오. 결과 집합의 스키마가 갑자기 증가하여 이전에 "빈" 열을 모두 포함하게 됩니다.결과 세트는 테이블의 메타데이터에만 의존하지 않고 결과 세트 전체가 일반 데이터에 의존하게 됩니다.

이 단순한 계획에서 벗어나지 않고 원하는 필드를 선택하기만 하면 됩니다.

언급URL : https://stackoverflow.com/questions/2219870/how-to-select-columns-from-a-table-which-have-non-null-values