#oracle #select #duplicates #distinct
#Oracle #выберите #дубликаты #distinct
Вопрос:
Я все еще вижу дубликаты в своих результатах после запуска SELECT DISTINCT
, несмотря на использование всех соответствующих методов для обеспечения того, чтобы повторяющиеся строки действительно дублировались (применение обрезки ко всем полям, форматирование полей даты только как даты и т. Д.). Я даже пытался GROUP BY
, но после его запуска дубликаты все равно появлялись. Есть ли у кого-нибудь хоть малейшее представление о том, что в мире происходит, и что я могу сделать?
SELECT DISTINCT
ID, Address_Line_1, Address_Line_2, City, State, Zip,
to_date(START_DATE, 'DD-MON-YYYY') as START_DATE,
to_date(END_DATE, 'DD-MON-YYYY') as END_DATE
FROM
AddressHistory
ORDER BY
ID, START_DATE DESC;
Комментарии:
1. Вы пробовали то, что я предложил, когда вы опубликовали тот же вопрос вчера? Я не вижу, чтобы TRUNC применялся к датам в вашем запросе в этом вопросе. Исходя из этого, предполагая, что «даты» действительно являются типом данных, почему вы применяете к ним TO_DATE? TO_DATE следует применять к строкам , чтобы преобразовать их в даты.
2. Предоставьте тестовый пример: СОЗДАЙТЕ ТАБЛИЦУ и ВСТАВЬТЕ В несколько выборочных строк (будет достаточно «E 3RD ST»), чтобы мы увидели, что у вас действительно есть, что возвращает ваш запрос и почему.
3. Каков тип данных столбцов start_date и end_date? Если это типы ДАТЫ, тогда используйте TRUNC — никогда не используйте TO_DATE для значения, которое уже является ДАТОЙ. Если они являются строковыми типами данных, то у вас могут быть такие значения, как «01-Jan-2020» и «01-JAN-2020», и еще один пример, почему никогда не следует хранить значения даты / времени в виде строки.
4. Если вы
select dump(column_name) from table
, вы увидите, что именно вычисляет каждый столбец / выражение в двоичном выводе и в чем разница. Без воспроизводимого примера я предполагаю, что одна из дат находится в столетии, отличном от того, которое вы ожидаете (т. Е. Одна дата приходится на 2013 год, а другая — на 1913 или 0013 год).). Но это всего лишь предположение без дополнительной информации.5. @mathguy, когда я выполняю Trunc(Start_Date), я получал следующую ошибку. Это было связано с тем, что в некоторых записях были нули, поэтому при обнаружении нулей выдавалась ошибка. Вот почему я попробовал что-то еще, но я понимаю, что вы говорите ORA-01722: недопустимый номер 01722. 00000 — «недопустимый номер» * Причина: указанный номер был недействительным. * Действие: укажите допустимое число.
Ответ №1:
Попробуйте
SELECT DISTINCT
ID, Address_Line_1, Address_Line_2, City, State, Zip,
trunc(to_date(START_DATE, 'DD-MON-YYYY')) as START_DATE,
trunc(to_date(END_DATE, 'DD-MON-YYYY')) as END_DATE FROM
AddressHistory
ORDER BY ID, START_DATE DESC;
Это сокращает время даты и выполняется быстрее, чем преобразование приведения типов.
Какой тип данных START_DATE в вашем примере? Возможно, вы можете полностью избавиться от приведения типов?
Комментарии:
1. Похоже, что комбинация использования обрезки вокруг определенных полей (для удаления скрытых символов) И подход trunc(to_date(START_DATE, ‘DD-MON-ГГГГ’)) as START_DATE решил проблему
Ответ №2:
Это связано с тем, что фактор времени в вашем столбце START_DATE
и END_DATE
не совпадает, вы должны получить distinct, если вы напишете свой запрос следующим образом.
SELECT DISTINCT * FROM
(
SELECT ID, Address_Line_1, Address_Line_2, City, State, Zip, to_date(START_DATE, 'DD-MON-YYYY') as START_DATE, to_date(END_DATE, 'DD-MON-YYYY') as END_DATE
FROM AddressHistory
)T
ORDER BY ID, START_DATE desc;
Комментарии:
1. Этот ответ неверен (несмотря на то, что один голос уже был поддержан). Неправильно, поскольку приложение TO_DATE находится в запросе OP, если оно не выдает ошибку, это приведет к датам с компонентом времени суток, равным полуночи.