Получить записи за ту же дату из таблицы в Oracle

Вопрос или проблема

У меня есть таблица, из которой я хочу получить записи, где 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

fiddle

Неясно, что именно хочет вопрос — единственное, что определенно, так это то, что локализованная строка даты вызовет проблемы. Она должна быть в формате 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) для избегания нежелательных ошибок.

Заключение

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

Оцените материал
Добавить комментарий

Капча загружается...