SQL-запрос: получить только не дублированный столбец в raw - PullRequest
0 голосов
/ 19 сентября 2019

Я пытаюсь сделать запрос к таблице следующим образом:

enter image description here

Мне нужен единственный столбец, который не дублируется вrow, в приведенном ниже примере мне нужно только: 15 для первой строки и 45 для второй, и если у меня несколько уникальных переменных, мне нужно, чтобы они все были такими, как 1,1,2,2,3,4,5 Я хочу 3,4,5

Чтобы у любого из вас была идея, как мне это сделатьв sql?Заранее спасибо.

Ответы [ 5 ]

0 голосов
/ 19 сентября 2019

Это будет обрабатывать null значения:

select
    id,
    trim(trailing ',' from concat(
        case when op1 in (op2, op3, op4, op5)
             then null else cast(op1 as varchar) + ',' end,
        case when op2 in (op1, op3, op4, op5)
             then null else cast(op2 as varchar) + ',' end,
        case when op3 in (op1, op2, op4, op5)
             then null else cast(op3 as varchar) + ',' end,
        case when op4 in (op1, op2, op3, op5)
             then null else cast(op4 as varchar) + ',' end,
        case when op5 in (op1, op2, op3, op4)
             then null else cast(op5 as varchar) + ',' end
        )
    )
from t;

Вы не можете использовать not in, когда список содержит null значений, но вы можете эффективно изменить логику с помощью case when <opX is dup> then null else <opX> end.

Вот пример работы с SQL Server.(Обратите внимание, что он не обрабатывает запятую. https://rextester.com/POYXO56613

0 голосов
/ 19 сентября 2019

Вот конкретный ответ Teradata с использованием unpivot

 select
    id,
    op_val
from
    <your table>
UNPIVOT ((op_val) for (op_type) in (op_1,op_2,op_3,op_4,op_5)) t
qualify  (count (*) over (partition by id,op_val) ) = 1

Меньше многословных, чем набор выражений или объединений падежей, хотя unpivot немного запутывает использование.Если вы просто запустите

select
*
from
<your table>
UNPIVOT ((op_val) for (op_type) in (op_1,op_2,op_3,op_4,op_5)) t

, это будет немного понятнее.5 столбцов op * становятся op_type, а значения в столбцах op * становятся op_val.

0 голосов
/ 19 сентября 2019

Отключить данные и агрегировать:

select id, op
from ((select id, op_1 as op, 1 as ind from t) union all
      (select id, op_2 as op, 2 as ind from t) union all
      (select id, op_3 as op, 3 as ind from t) union all
      (select id, op_4 as op, 4 as ind from t) union all
      (select id, op_5 as op, 5 as ind from t) 
     ) t
group by id, op
having count(*) = 1;

Вы также можете сделать это с массивным case.Если у вас нет значений null:

select id,
       (case when op1 not in (op2, op3, op4, op5) then op1
             when op2 not in (op1, op3, op4, op5) then op2
             when op3 not in (op1, op2, op4, op5) then op3
             when op4 not in (op1, op2, op3, op5) then op4
             when op5 not in (op1, op2, op3, op4) then op5
        end) as unique_op
from t;
0 голосов
/ 19 сентября 2019

Вы можете использовать любой из указанных ниже вариантов в соответствии с вашими требованиями -

SELECT ID,
CASE WHEN op_1 NOT IN (op_2,op_3,op_4,op_5) THEN op_1 ELSE NULL END op_1,
CASE WHEN op_2 NOT IN (op_1,op_3,op_4,op_5) THEN op_2 ELSE NULL END op_2,
CASE WHEN op_3 NOT IN (op_1,op_2,op_4,op_5) THEN op_3 ELSE NULL END op_3,
CASE WHEN op_4 NOT IN (op_1,op_2,op_3,op_5) THEN op_4 ELSE NULL END op_4,
CASE WHEN op_5 NOT IN (op_1,op_2,op_3,op_4) THEN op_5 ELSE NULL END op_5
FROM your_table 

Выход -

ID      op_1    op_2    op_3    op_4    op_5
12345                                   15
12346                   45      

Или параметр -2

SELECT ID,op_1 AS VALUE
FROM your_table WHERE op_1 NOT IN (op_2,op_3,op_4,op_5)

UNION ALL

SELECT ID,op_2 AS VALUE
FROM your_table WHERE op_2 NOT IN (op_1,op_3,op_4,op_5)

UNION ALL

SELECT ID,op_3 AS VALUE
FROM your_table WHERE op_3 NOT IN (op_1,op_2,op_4,op_5)

UNION ALL

SELECT ID,op_4 AS VALUE
FROM your_table WHERE op_4 NOT IN (op_1,op_2,op_3,op_5)

UNION ALL

SELECT ID,op_5 AS VALUE
FROM your_table WHERE op_5 NOT IN (op_1,op_2,op_3,op_4)

Выход -

ID      VALUE
12346   45
12345   15
0 голосов
/ 19 сентября 2019

Стандартный SQL-выбор определяет столбцы, которые вы хотите получить, поэтому я не понимаю, как стандартный выбор можно использовать для непосредственного извлечения данных.

Так как бы мы это сделали?

Я думаю, что «SQL» можно было бы создать таблицу (которая может быть временной таблицей) и вставить в нее значения, которые мы хотим вернуть.

В вашем примере (я подозреваю, что реальная жизньзначительно более сложным), то мы бы создали таблицу с двумя столбцами ID и UniqueOp;Поскольку в любой строке может быть более одного уникального оператора, вы не захотите делать ни один из них первичным ключом, но мы могли бы сделать оба первичных ключа (как если бы Op дублировался, он не будет уникальным).

Затем заполните таблицу с помощью выбора.


DROP TABLE tblResults IF EXISTS;
CREATE TABLE tblResults(ID Int(11) NOT NULL, UniqueOp INT(11) NOT NULL PRIMARY KEY(ID, UniqueOp));

INSERT INTO tblResults(ID, UniqueOp) (SELECT ID, Op_1 FROM tblBase WHERE Op_1<>Op_2 AND Op_1<>Op_3 AND Op_1<>Op_4 AND Op_1<>Op_5);
INSERT INTO tblResults(ID, UniqueOp) (SELECT ID, Op_2 FROM tblBase WHERE Op_2<>Op_1 AND Op_2<>Op_3 AND Op_2<>Op_4 AND Op_2<>Op_5);
INSERT INTO tblResults(ID, UniqueOp) (SELECT ID, Op_3 FROM tblBase WHERE Op_3<>Op_1 AND Op_3<>Op_2 AND Op_3<>Op_4 AND Op_3<>Op_5);
INSERT INTO tblResults(ID, UniqueOp) (SELECT ID, Op_4 FROM tblBase WHERE Op_4<>Op_1 AND Op_4<>Op_2 AND Op_4<>Op_3 AND Op_4<>Op_5);
INSERT INTO tblResults(ID, UniqueOp) (SELECT ID, Op_5 FROM tblBase WHERE Op_5<>Op_1 AND Op_5<>Op_2 AND Op_5<>Op_3 AND Op_5<>Op_4);

SELECT ID, UniqueOp FROM tblResults;

...