Вопрос или проблема
У меня есть таблица, из которой я хочу получить записи, где MODIFIED_DATE
совпадает с количеством 2
.
Например: если для job_id
= 1234 есть 2 записи с датой MODIFIED_DATE
= 04-10-2024
, то эта запись должна быть отфильтрована.
Name Null? Type
---------------------- -------- --------------
JOB_PROGRESS_ID NOT NULL NUMBER
JOB_ID NUMBER
STATUS_ID NUMBER
HOTO_OFFERED_DATE DATE
HOTO_ACCEPTENCE_DATE DATE
LIT_ACCEPTENCE_DATE DATE
APPROVED_BY NVARCHAR2(200)
APPROVED_DATE DATE
REJECTED_BY NVARCHAR2(200)
REJECTED_DATE DATE
APPROV_REJECT_REMARK NVARCHAR2(255)
ABD_COMPLETED_LENGTH NUMBER
NE_SPAN_LENGTH NUMBER(10,4)
CREATED_BY NVARCHAR2(200)
CREATED_DATE NOT NULL DATE
MODIFIED_BY NVARCHAR2(200)
MODIFIED_DATE DATE
Если вы хотите найти job_id
и modified_date
там, где в таблице есть две строки с этими значениями, то можно выполнить:
SELECT job_id, modified_date
FROM table_name
GROUP BY job_id, modified_date
HAVING COUNT(*) = 2
Для примера данных:
CREATE TABLE table_name (job_id, modified_by, modified_date) AS
SELECT 1, 'Alice', DATE '2024-10-04' FROM DUAL UNION ALL
SELECT 1, 'Betty', DATE '2024-10-04' FROM DUAL UNION ALL
SELECT 2, 'Carol', DATE '2024-10-04' + INTERVAL '01:23:45' HOUR TO SECOND FROM DUAL UNION ALL
SELECT 2, 'Debra', DATE '2024-10-04' + INTERVAL '23:59:59' HOUR TO SECOND FROM DUAL UNION ALL
SELECT 3, 'Emily', DATE '2024-10-04' FROM DUAL;
Результаты:
JOB_ID | MODIFIED_DATE |
---|---|
1 | 2024-10-04 00:00:00 |
Если вы хотите перечислить все столбцы, то можно использовать:
SELECT *
FROM (
SELECT t.*,
COUNT(*) OVER (PARTITION BY job_id, modified_date)
AS num_duplicates_per_job_per_day
FROM table_name t
)
WHERE num_duplicates_per_job_per_day = 2
Результаты:
JOB_ID | MODIFIED_BY | MODIFIED_DATE | NUM_DUPLICATES_PER_JOB_PER_DAY |
---|---|---|---|
1 | Alice | 2024-10-04 00:00:00 | 2 |
1 | Betty | 2024-10-04 00:00:00 | 2 |
Примечание: DATE
всегда имеет компонент даты и времени, поэтому, когда вы сравниваете значения, вы сравниваете с точностью до секунд (не до дней). Если вы храните не полуночные временные компоненты и хотите проверить дубликаты в течение всего дня, используйте TRUNC(modified_date)
, а не modified_date
в запросах.
SELECT job_id, TRUNC(modified_date)
FROM table_name
GROUP BY job_id, TRUNC(modified_date)
HAVING COUNT(*) = 2;
Результаты:
JOB_ID | TRUNC(MODIFIED_DATE) |
---|---|
2 | 2024-10-04 00:00:00 |
1 | 2024-10-04 00:00:00 |
и:
SELECT *
FROM (
SELECT t.*,
COUNT(*) OVER (PARTITION BY job_id, TRUNC(modified_date))
AS num_duplicates_per_job_per_day
FROM table_name t
)
WHERE num_duplicates_per_job_per_day = 2;
Результаты:
JOB_ID | MODIFIED_BY | MODIFIED_DATE | NUM_DUPLICATES_PER_JOB_PER_DAY |
---|---|---|---|
1 | Alice | 2024-10-04 00:00:00 | 2 |
1 | Betty | 2024-10-04 00:00:00 | 2 |
2 | Carol | 2024-10-04 01:23:45 | 2 |
2 | Debra | 2024-10-04 23:59:59 | 2 |
Неясно, что именно хочет вопрос — единственное, что определенно, так это то, что локализованная строка даты вызовет проблемы. Она должна быть в формате YYYY-MM-DD
.
Вопрос может касаться того, как найти все дублирующиеся строки, одну из дублирующихся строк или рабочие записи с дубликатами.
Чтобы найти JobID с 2 или более строками в одну и ту же дату, можно использовать GROUP BY
с HAVING
:
Select JOB_ID, Modified_Date, Count(*)
FROM That_Table
GROUP BY JOB_ID, Modified_Date
Having Count(*)>1
Чтобы найти все дубликаты за день, можно использовать CTE с COUNT() OVER
:
With multiples as
(
Select * ,
COUNT(*) OVER (PARTITION BY JOB_ID, Modified_Date) as cnt
FROM That_Table
)
select That_Table.*
from multiples
where cnt=2
Чтобы найти только лишнюю строку, можно использовать ROW_NUMBER
:
With multiples as
(
Select That_Table.* ,
ROW_NUMBER(*) OVER (
PARTITION BY JOB_ID, Modified_Date
Order BY JOB_PROGRESS_ID) as RN
From That_Table
)
select multiples.*
from multiples
where RN>1
Ответ или решение
Для получения записей из таблицы в Oracle, где значения MODIFIED_DATE
совпадают и количество таких записей равно 2, можно воспользоваться оператором GROUP BY
и условием HAVING
. Ниже приведены несколько подходов для выполнения этой задачи.
1. Получение уникальных job_id
и modified_date
с количеством 2:
Если вам необходимо получить только job_id
и modified_date
для тех записей, которые соответствуют вашему критерию, используйте следующий запрос:
SELECT job_id, modified_date
FROM table_name
GROUP BY job_id, modified_date
HAVING COUNT(*) = 2;
2. Выбор всех колонок из таблицы для дублирующихся записей:
Если вы хотите получить полные записи, включая все столбцы, связанных с job_id
и modified_date
, где количество равно 2, можно использовать оконную функцию COUNT() OVER
:
SELECT *
FROM (
SELECT t.*,
COUNT(*) OVER (PARTITION BY job_id, modified_date) AS num_duplicates_per_job
FROM table_name t
)
WHERE num_duplicates_per_job = 2;
3. Учет времени при поиске дубликатов:
Поскольку тип данных DATE
в Oracle содержит как дату, так и время, для проверки дубликатов по дате без учета времени рекомендуется использовать функцию TRUNC()
:
SELECT job_id, TRUNC(modified_date) AS modified_date
FROM table_name
GROUP BY job_id, TRUNC(modified_date)
HAVING COUNT(*) = 2;
Для получения всех колонок с учетом времени:
SELECT *
FROM (
SELECT t.*,
COUNT(*) OVER (PARTITION BY job_id, TRUNC(modified_date)) AS num_duplicates_per_job
FROM table_name t
)
WHERE num_duplicates_per_job = 2;
4. Примечание по формату даты:
Обратите внимание, что при сравнении значений в базе данных с использованием типа DATE
важно учитывать, что сравнения происходят с точностью до секунд. Поэтому, если вы работаете с записью, содержащей временные элементы, используйте TRUNC(modified_date)
для избегания нежелательных ошибок.
Заключение
Представленные выше запросы помогут вам извлечь те записи, которые соответствуют заданным критериям по дублирующимся датам. Выбор подходящего метода зависит от нужда вашего анализа и требований к результатам.