programing

한 두 필드만 빼고 다 선택할 수 있어요? 작가 경련 없이?

goodsources 2023. 2. 10. 21:47
반응형

한 두 필드만 빼고 다 선택할 수 있어요? 작가 경련 없이?

PLSQL에서는 원하는 필드를 지정하지 않고 테이블 내의 1 또는2 이외의 모든 필드를 선택할 수 있습니까?

예를 들어 직원 테이블에는 다음 필드가 있습니다.

  • 아이디
  • 이름
  • 취미들

여전히 다음과 유사한 쿼리를 작성할 수 있습니까?

select * from employee

hobbies런런 걸걸 ?? ?? ???

select id, firstname, lastname from employee

아니요 - 모든 *필드를 가져오거나() 원하는 필드를 지정합니다.

작성자의 경련을 방지하려면 SQL Developer를 사용하여 열 목록을 생성할 수 있습니다.

select column_name||','
from all_tab_columns
where table_name = 'YourTableName'

그런 다음 원하지 않는 열을 하나 또는 두 개만들면 됩니다.

를 사용할 수도 있습니다.

SELECT listagg(column_name, ',') within group (order by column_name) columns
FROM all_tab_columns
WHERE table_name = 'TABLE_NAME'
GROUP BY table_name;

오래된 실타래지만, 그래...Oracle에는 다음과 같은 방법이 있습니다.

with

employee(id, firstname, lastname, hobbies) as
(
  select 1, 'a', 'b', '1' from dual union 
  select 2, 'a', 'b', '2' from dual union 
  select 3, 'a', 'b', '3' from dual union 
  select 4, 'c', 'd', '3' from dual union 
  select 5, 'e', 'f', '2' from dual  
)

select * 
from employee 
pivot
( 
  max(1) -- fake  
  for (hobbies) -- put the undesired columns here
  IN () -- no values here...
) 
where 1=1 -- and your filters here...
order by id

피벗이 어떻게 작동하며 문제를 해결하는지를 이해하기 위해 NAT과 NAT, NAT, NAT의employee「이것들」은 다음과 같습니다.

select * 
from employee 
pivot
(
  max(id) foo,
  max(1)  bar
  for (hobbies) 
  IN ('2' as two, '3' as three)
)

결과는 다음과 같습니다.

FIRST NAME | LASTNAME | TWO_FOO | TWO_BAR | TWO_FOO | TWO_BARc d null 4 1e f 5 1의 특수한 순서a b 2 1 3 1

이해하기 쉬운 쿼리를 사용하여 동일한 출력을 얻을 수 있습니다.

select 
  firstname,
  lastname,
  max(case when hobbies = '2' then id end) two_foo,
  max(case when hobbies = '2' then 1  end) two_bar,
  max(case when hobbies = '3' then id end) three_foo,
  max(case when hobbies = '3' then 1  end) three_bar
from employee 
group by
  firstname,
  lastname

hobbies is is is is is 。id둘 다 PIVTOB 구 에서 지정됩니다.다른 모든 열은 그룹화되어 선택됩니다.

첫 두 로 효과가 있습니다.
1- id 열은 고유하고 집계에 대해 지정된 열이 없기 때문에 그룹화 프로세스에서 행이 손실되지 않습니다.
2- 피벗이 N * M 새 열을 생성합니다. 여기서 N = IN 절의 값 수 및 M = 지정된 집계 수이므로 필터가 없고 단일 무해한 집계가 0 * 1 = 0 새 열을 생성하며 PIVOT 에 지정된 열은 제거되며, 이는 취미에 불과하다.


코멘트 1에 대한 답변

이 질문의 첫 번째 행은 "...원하는 필드를 지정하지 않아도 됩니다."다른 모든 답변에서는 제안된 쿼리가 실제로 select 에서 원하는 필드를 지정합니다(mine은 제외).

그리고 문제 제목에 '작가님 쥐 안 나세요'라고 써있는데요.글쓴이의 경련을 확인하는 올바른 방법은 무엇일까요?이 문제에 대한 적절한 SQL 표준을 예측하고 답변과 비교하는 것이 최선의 방법입니다.사실 이 "표준"은 SELECT * NOT IN([col1], [col2], ...)과 같은 것일 수 있습니다.

이제 두 가지 쿼리에서 모두 확인할 수 있습니다.

  • 원치 않는 열의 목록
  • IN 조항
  • 3글자(FOR 및 NOT) 조항

즉, 당신은 가짜 집계를 필요로 하기 때문에 나의 접근법에 조금 더 글을 써야 합니다.그리고 PIVOT 조항은...글자 수가 너무 적어서...

Oracle 12c에서 실행 중입니까?

만약 그렇다면, 이것이 당신의 요구를 충족시키는지 고려하세요.

alter table mytable modify column undesired_col_name INVISIBLE;

[ ]컬럼은 [ ]undesired_col_name 사용할 수 , 전전사사 any any any, will any will will will any any any any any any any any any any any any any any any any any any any any any에서 됩니다.SELECT * 「」)을 참조해 주세요).%ROWTYPE마치 존재하지 않는 것처럼요.

Oracle 18c 다형 테이블 함수를 사용하면 테이블에서 모든 항목을 선택하고 열 목록을 제외할 수 있습니다.

select * from everything_but(employee, columns(hobbies));

ID   FIRSTNAME   LASTNAME
--   ---------   --------
1    John        Smith

이 기능을 만들려면 Tim Hall 웹사이트 https://oracle-base.com/articles/18c/polymorphic-table-functions-18c에서 복사한 다음 패키지가 필요합니다.패키지에는 테이블 고유의 내용이 포함되어 있지 않습니다.이 솔루션은 모든 Oracle 테이블에서 사용할 수 있습니다.

CREATE OR REPLACE PACKAGE poly_pkg AS

  FUNCTION everything_but(tab IN TABLE,
                          col IN COLUMNS)
  RETURN TABLE PIPELINED
  ROW POLYMORPHIC USING poly_pkg;

  FUNCTION describe (tab IN OUT DBMS_TF.table_t,
                     col IN     dbms_tf.columns_t)
    RETURN DBMS_TF.describe_t;

END poly_pkg;
/


CREATE OR REPLACE PACKAGE BODY poly_pkg AS

  FUNCTION describe (tab IN OUT DBMS_TF.table_t,
                     col IN     dbms_tf.columns_t)
    RETURN DBMS_TF.describe_t
  AS
  BEGIN
    -- Loop through all the table columns.
    FOR i IN 1 .. tab.column.count() LOOP
      -- Loop through all the columns listed in the second parameter.
      FOR j IN 1 .. col.count() LOOP
        -- Set pass_through to true for any columns not in the exclude list.
        tab.column(i).pass_through := (tab.column(i).description.name != col(j));
        -- Exit inner loop if you find a column that shouldn't be included.
        EXIT WHEN NOT tab.column(i).pass_through;
      END LOOP;
    END LOOP;

    RETURN NULL;
  END;

END poly_pkg;
/

이 간단한 포장 기능도 더 좋은 이름을 붙이기 위해 만들었습니다.그리고 간단한 예제 표를 만들었습니다.

CREATE OR REPLACE FUNCTION everything_but(tab IN TABLE, col in COLUMNS)
  RETURN TABLE PIPELINED
  ROW POLYMORPHIC USING poly_pkg;
/

create table employee as
select 1 id, 'John' firstname, 'Smith' lastname, 'fishing' hobbies from dual;

query_generator는 테이블(첫 번째 파라미터)의 선택 문자열을 반환하지만 일부 열(두 번째 파라미터)은 반환하지 않는 PL/SQL 함수입니다.

stringlist ★★★★★★★★★★★★★★★★★」putil.joinPL/SQL Commons의 입니다.

stringlist입니다.create type StringList as table of varchar2(32767); ★★★★★★★★★★★★★★★★★」putil.join그냥 일반적인 결합 함수입니다.

create or replace function quote_list(p_list in stringlist)
return stringlist as
  v_list stringlist := stringlist();
begin
  v_list.extend(p_list.last);
  for i in p_list.first .. p_list.last loop
    v_list(i) := '''' || p_list(i) || '''';
  end loop;

  return v_list;
end;
/
show errors

create or replace function query_generator(
  p_table in varchar2,
  p_exclude in stringlist
) return varchar2 as
  v_table constant varchar2(31) := upper(p_table);
  v_exclude constant varchar2(32676) :=
    upper(putil.join(quote_list(p_exclude), ','));
  v_stmt_str constant varchar2(32676) :=
    'select column_name from all_tab_columns where table_name = ''' ||
    v_table || ''' and column_name not in (' || v_exclude ||
    ') order by column_id';
  type stmt_cur_t is ref cursor;
  v_stmt_cur stmt_cur_t;
  v_column_name varchar2(31);
  v_query varchar2(32676) := 'select ';
begin
  open v_stmt_cur for v_stmt_str;

  loop
    fetch v_stmt_cur into v_column_name;
    exit when v_stmt_cur%notfound;
    v_query := v_query || lower(v_column_name) || ', ';
  end loop;

  close v_stmt_cur;

  select rtrim(v_query, ', ') into v_query from dual;

  v_query := v_query || ' from ' || p_table || ';';

  return v_query;
end;
/
show errors

사용 예:

exec dbms_output.put_line(query_generator('all_tables', stringlist('segment_created', 'result_cache')))

뷰를 작성하려면:-

view_name을 id, first_name, last_name을(를) 종업원으로부터 선택해 작성합니다.여기서 id는 ('', ).

주의: 이것은 데이터베이스 내의 가상 테이블과 비슷하지만 실제 테이블의 값에 영향을 줄 수 있습니다.

WITH O AS
(
SELECT 'SELECT ' || rtrim('NULL AS "Dummy",' || LISTAGG('"'||column_name || '"', ',' ) within group (ORDER BY COLUMN_NAME),',')|| ' FROM "'||TABLE_NAME||'"' AS SQL, TABLE_NAME  FROM USER_TAB_COLUMNS  GROUP BY (TABLE_NAME)
)
SELECT DBMS_XMLGEN.GETXMLTYPE ((SELECT REPLACE(SQL,',COLUMNNAME','') FROM O WHERE TABLE_NAME = 'TABLENAME')) FROM DUAL

OP가 찾고 있는 것은 다음과 같습니다.

SELECT * MINUS hobbies from...

많은 입력을 피하려면(그리고 모든 열 이름을 맞춥니다) 가장 좋은 방법은 표 설명을 열고 모든 열 이름을 잘라 붙여넣은 다음 원하지 않는 열 이름을 삭제하고 나머지 열 이름을 쉼표로 구분하여 한 줄 또는 두 줄에 넣는 것입니다.

이것은 쉽고, 빠르고, 정확하며, 코드 작업을 해야 하는 다음 사용자를 혼란스럽게 하지 않습니다.

딜리미터를 지정할 수 있는 필드 목록을 가져오는 다른 옵션은 다음과 같습니다.

select listagg(column_name, ', ') WITHIN GROUP (ORDER BY rownum)
from all_tab_columns
where table_name='table'

여기 해결책이 있습니다...암호를 제외한 모든 열이 필요합니다.

( column_name ||' , user_tab_module 에서 table_name ='USER' 및 column_name <> 를 선택합니다).패스워드')

이것이 SAS가 수십 년 동안 Implicit SQL 및 DATA STEP에 DROP 조항을 제공해 온 이유입니다.

myDB.mytable(drop=mytable)에서 t.*를 선택합니다.

또는

myDB.mytable t에서 t.선택하여 table /* 또는 view / mytable(drop=drop)을 만듭니다.

즉, "myDB"가 가리키는 RDMB의 수와 상관없습니다.ORACLE, Teradata, SAS, DB2, Netezza 등명시적인 데이터베이스 SQL을 RDMB에 제출하기 전에 SAS는 모든 열 이름을 수집하고 지정한 이름을 삭제하며 프로그래밍 방식으로 원하는 열만 포함하는 SELECT 문을 만듭니다.

언급URL : https://stackoverflow.com/questions/9133120/can-you-select-everything-but-1-or-2-fields-without-writers-cramp

반응형