Oracle — уникальные комбинации значений из нескольких столбцов, но возвращающие другие столбцы

#sql #oracle #distinct #aggregate-functions

#sql #Oracle #различные #агрегатные функции

Вопрос:

Я пытаюсь выяснить, как извлекать различные сценарии данных из моей таблицы для тестирования. Предположим, что в моей таблице есть эти три поля FIELD1, FIELD2, FIELD3 . Если я хочу найти различные сценарии в своих данных, я мог бы просто сделать это

 select distinct FIELD1, FIELD2, FIELD3 from <table>
  

И это работает. Проблема в том, что у меня есть множество других полей, из которых мне также нужны данные, но не имеет значения, что это за данные, если они связаны с результирующей записью. Так, например, если приведенный выше запрос вернул это как один из результатов

 FIELD1  FIELD2  FIELD3
----------------------
Y       Blue    31
  

Я бы хотел увидеть другие поля содержимого (скажем, с 4 по 10). Теперь, были ли они получены из записи № 30 или записи № 20000 (при условии, что эти записи содержали эти 3 возвращаемых значения), это не имеет значения, если все поля были возвращены указанной записью.

Надеюсь, это имеет смысл, и кто-нибудь может помочь!

Комментарии:

1. Все ли значения в FIELD4 — FIELD10 должны поступать из одной и той же записи? Или поле 4 может быть получено из записи # 30, а ПОЛЕ 5 — из записи # 20000 и т.д.?

2. @Shannon — Я думаю, что нет, но это было бы предпочтительнее.

Ответ №1:

Что-то вроде

 SELECT field1, 
       field2,
       field3,
       field4,
       ....
       field10
  FROM( SELECT field1,
               field2,
               ...,
               field10,
               rowid rid,
               min(rowid) OVER (partition by field1, field2, field3) min_rid
          FROM your_table_name )
 WHERE rid = min_rid
  

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

Для вашего curveball

 SELECT field1, 
       field2,
       field3,
       field4,
       ....
       field10
  FROM( SELECT field1,
               field2,
               (CASE WHEN field3 IS NULL
                     THEN 'NULL'
                     ELSE field3
                 END) field3,
               ...,
               field10,
               rowid rid,
               min(rowid) OVER (partition by field1, 
                                             field2, 
                                             (CASE WHEN field3 IS NULL
                                                   THEN 'NULL'
                                                   ELSE field3
                                               END) min_rid
          FROM your_table_name )
 WHERE rid = min_rid
  

Комментарии:

1. Потрясающе — требуется некоторое время, чтобы разобраться, но я воспринимаю это как хороший знак. хотя 1 кривой шар. Допустим, поле 3 может быть нулевым или иметь некоторое значение. Когда значение не равно null, я хочу обрабатывать их одинаково. Что-то похожее на этот случай, когда field3 равно null, тогда null else ‘X’ заканчивается как field3, просто не уверен, как бы я реализовал это как во внешнем выборе, так и в разделе.

2. @dscl — Покрыл кривизну

3. Спасибо, Джастин, я попробовал это самостоятельно и почти справился с этим, просто возникла проблема с ‘( )’.

Ответ №2:

Попробуйте это:

 select a.* 
from tblA a, 
     (select min(rowid), col_1, col_2 from tblA
      group by col_1, col_2) b
where a.rowid=b.rid;