SQL: вернуть только те столбцы с разными данными - PullRequest
1 голос
/ 11 февраля 2011

У меня есть две строки из таблицы, которая имеет много столбцов. Как вернуть только те столбцы, где значение для строки1 не равно значению для строки2?

Я использую Oracle 11.1.0.07

~~ Редактировать: уточнение ~~

Пример: Итак, у меня есть таблица со строками:

1 a b c d e f g h i j k l
2 a x c d e x g h y j k l
3 a b x d e x g h x y k z

Я хочу вернуть строки, где id (первый столбец) равен 1 или 3, только те столбцы, которые отличаются. Итак:

1 c f i j l
3 x x x y z

с именами столбцов.

На самом деле таблица, из которой я берусь, имеет 223007 строк и 40 столбцов. Выше приведен упрощенный пример. Есть две строки (по одной для значений первичного ключа), которые я хочу сравнить.

Ответы [ 4 ]

3 голосов
/ 11 февраля 2011

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

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

With Inputs As
    (
    Select 1 As Col1,'a' As Col2,'b' As Col3,'c' As Col4,'d' As Col5,'e' As Col6,'f' As Col7,'g' As Col8,'h' As Col9,'i' As Col10,'j' As Col11,'k' As Col12,'l' As Col13
    Union All Select 2,'a','x','c','d','e','x','g','h','y','j','k','l'
    Union All Select 3,'a','b','x','d','e','x','g','h','x','y','k','z'
    )
    , TransposedInputs As
    (
    Select Col1, 2 As ColNum, Col2 As Value From Inputs
    Union All Select Col1, 3, Col3 From Inputs
    Union All Select Col1, 4, Col4 From Inputs
    Union All Select Col1, 5, Col5 From Inputs
    Union All Select Col1, 6, Col6 From Inputs
    Union All Select Col1, 7, Col7 From Inputs
    Union All Select Col1, 8, Col8 From Inputs
    Union All Select Col1, 9, Col9 From Inputs
    Union All Select Col1, 10, Col10 From Inputs
    Union All Select Col1, 11, Col11 From Inputs
    Union All Select Col1, 12, Col12 From Inputs
    Union All Select Col1, 13, Col13 From Inputs
    )
    , UniqueValues As
    (
    Select Min(Col1) As Col1, ColNum, Value
    From TransposedInputs
    Where Col1 In(1,3)
    Group By ColNum, Value
    Having Count(*) = 1
    )
Select Col1
    , Min( Case When ColNum = 2 Then Value End ) As Col2
    , Min( Case When ColNum = 3 Then Value End ) As Col3
    , Min( Case When ColNum = 4 Then Value End ) As Col4
    , Min( Case When ColNum = 5 Then Value End ) As Col5
    , Min( Case When ColNum = 6 Then Value End ) As Col6
    , Min( Case When ColNum = 7 Then Value End ) As Col7
    , Min( Case When ColNum = 8 Then Value End ) As Col8
    , Min( Case When ColNum = 9 Then Value End ) As Col9
    , Min( Case When ColNum = 10 Then Value End ) As Col10
    , Min( Case When ColNum = 11 Then Value End ) As Col11
    , Min( Case When ColNum = 12 Then Value End ) As Col12
    , Min( Case When ColNum = 13 Then Value End ) As Col13
From UniqueValues
Group By Col1

Результаты:

Col1 | Col2      | Col3      | Col4  | Col5      | Col6      | Col7  | Col8      | Col9      | Col10 | Col11 | Col12     | Col13
1   |   NULL    |   NULL    |   c   |   NULL    |   NULL    |   f   |   NULL    |   NULL    |   i   |   j   |   NULL    |   l
3   |   NULL    |   NULL    |   x   |   NULL    |   NULL    |   x   |   NULL    |   NULL    |   x   |   y   |   NULL    |   z
3 голосов
/ 11 февраля 2011

Если вы пытаетесь транспонировать или pivot ваши строки1 и строки2 в столбцы, тогда вам могут помочь следующие вопросы:

После поворота вы можете выбрать только те кортежи, которые имеют row1_pivoted <> row2_pivoted

1 голос
/ 11 февраля 2011

Хм.Первый удар в ответ был неправильным, когда я перечитал вопрос.Итак ... для пояснения, у вас есть несколько строк / значений

  1. abc
  2. def
  3. abc

и выХотелось бы, чтобы возвращалась только строка 'def', потому что она не имеет повторяющейся строки в другом месте?

0 голосов
/ 11 февраля 2011

Количество столбцов в наборе результатов не может быть динамическим (без обращения к динамическому SQL).

Возможно, вас заинтересует оператор Unpivot .Это позволит вам вернуть столбцы в виде строк.Я сам еще не экспериментировал с этим, поэтому, к сожалению, я не могу вам с этим помочь: /

Редактировать

Я хотел сделать поворот вручную:)

select *
  from inputs;

 ID C1 C2 C3 C4 C5 C6
--- -- -- -- -- -- --
  1  a  b  c  d  e  f
  2  a  x  c  d  e  x
  3  a  b  x  d  e  x 

with unpivoted as(
  select id, 'c1'  as cn, c1  as cv from inputs union all
  select id, 'c2'  as cn, c2  as cv from inputs union all
  select id, 'c3'  as cn, c3  as cv from inputs union all
  select id, 'c4'  as cn, c4  as cv from inputs union all
  select id, 'c5'  as cn, c5  as cv from inputs union all
  select id, 'c6'  as cn, c6  as cv from inputs
)
select cn
      ,max(case when id = 1 then cv end) as id1
      ,max(case when id = 3 then cv end) as id3
  from unpivoted
 where id in(1,3)
 group 
    by cn
 having count(distinct cv) = 2;


CN ID1 ID3
-- --- ---
c3   c   x
c6   f   x

Вышеописанное работает путем создания одной строки для каждого столбца и идентификатора (2 * 6 = 12 строк).
Затем я группирую по имени столбца (назначается как литерал).Я всегда получу 6 групп (по одной на каждый столбец).В каждой группе у меня будет ровно две строки (по одной для каждого выбранного идентификатора).
В предложении Имеется количество уникальных значений для столбца.Если строки имеют одно и то же значение, то число уникальных значений = 1. В противном случае мы имеем несоответствие.

Примечание 1. id in(x,y) выталкивается в представление, поэтому мы не выбирая всю таблицу.
Примечание 2. Это не может быть расширено для сравнения более 2 строк.
Примечание 3. Это не относится к NULLS ни в одном из столбцов

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...