Сокращение и группирование записей и замена значения в поле

#sql #oracle #duplicates

#sql #Oracle #дубликаты

Вопрос:

Для примера я выбрал только две ссылки на исправление в запросе. На выходе отображается количество записей для каждой ссылки на восстановление. Для каждого ремонта может быть несколько последовательностей, и для каждой последовательности ему назначается специалист по торговле (показано ниже):

 ╔══════════════════╦══════════════╦══════════════╦════════════╦═══════════════╗
║ Repair Reference ║ Tenant Name  ║ Job Sequence ║ Trade Code ║ Trade         ║
╠══════════════════╬══════════════╬══════════════╬════════════╬═══════════════╣
║         57257795 ║ MISS L SMITH ║            141 ║ Plumber       ║
║         57257795 ║ MISS L SMITH ║           1040 ║ Plasterer     ║
║         57257795 ║ MISS L SMITH ║           1140 ║ Plasterer     ║
║         57257795 ║ MISS L SMITH ║           1340 ║ Plasterer     ║
║         57257795 ║ MISS L SMITH ║           1444 ║ Electrician   ║
║         57257795 ║ MISS L SMITH ║           1544 ║ Electrician   ║
║         57257795 ║ MISS L SMITH ║           1740 ║ Plasterer     ║
║         57257795 ║ MISS L SMITH ║           1841 ║ Plumber       ║
║         57257795 ║ MISS L SMITH ║           1941 ║ Plumber       ║
║         57257795 ║ MISS L SMITH ║            241 ║ Plumber       ║
║         57257795 ║ MISS L SMITH ║           2032 ║ Joiner        ║
║         57257795 ║ MISS L SMITH ║            340 ║ Plasterer     ║
║         57257795 ║ MISS L SMITH ║            532 ║ Joiner        ║
║         57257795 ║ MISS L SMITH ║            640 ║ Plasterer     ║
║         57257795 ║ MISS L SMITH ║            740 ║ Plasterer     ║
║         57257795 ║ MISS L SMITH ║            832 ║ Joiner        ║
║         57342819 ║ MISS A GREEN ║            140 ║ Plasterer     ║
║         57342819 ║ MISS A GREEN ║            240 ║ Plasterer     ║
║         57342819 ║ MISS A GREEN ║            333 ║ Painter       ║
║         57342819 ║ MISS A GREEN ║            433 ║ Painter       ║
║         57342819 ║ MISS A GREEN ║            533 ║ Painter       ║
║         57342819 ║ MISS A GREEN ║            640 ║ Plasterer     ║
╚══════════════════╩══════════════╩══════════════╩════════════╩═══════════════╝
  

Клиент хочет, чтобы для каждой ссылки на восстановление отображалась только одна запись (пример показан ниже) — я могу сделать это с помощью Job_Sequence = 1 . Проблема, с которой я сталкиваюсь, заключается в том Trade , чтобы показать Multi Trade , существует ли более одного Trade типа для каждого Repair Reference . Это то, с чем я борюсь. Можно ли просмотреть все Trades per Repair Reference , и если существует более одного типа, отобразить текст Multi Trade в противном случае, если Trade/Trade Code для a есть только один Repair Reference , тогда просто используйте сделку как есть:

 ╔══════════════════╦══════════════╦══════════════╦════════════╦══════════════╗
║ Repair Reference ║ Tenant Name  ║ Job Sequence ║ Trade Code ║    Trade     ║
╠══════════════════╬══════════════╬══════════════╬════════════╬══════════════╣
║         57257795 ║ MISS L SMITH ║            141 ║ Multi Trade  ║
║         57342819 ║ MISS A GREEN ║            140 ║ Multi Trade  ║
╚══════════════════╩══════════════╩══════════════╩════════════╩══════════════╝
  

Вот SQL, который у меня есть в настоящее время:

 SELECT
rhm_job_seqs.repair_ref AS "Repair Reference",
rhm_repairs.tenant_name AS "Tenant Name",
rhm_repairs.tenant_address1 AS "Tenant Address1",
rhm_repairs.tenant_address2 AS "Tenant Address2",
rhm_repairs.tenant_postcode AS "Tenant PostCode",
rhm_job_seqs.job_seq AS "Job Sequence",
rhm_trades.trade_code AS "Trade Code",
rhm_trades.trade_desc AS "Trade"
FROM (
RHM_REPAIRS
INNER JOIN RHM_JOB_SEQS ON RHM_REPAIRS.REPAIR_REF = RHM_JOB_SEQS.REPAIR_REF)
INNER JOIN RHM_OPERATORS ON RHM_JOB_SEQS.OPERATOR_ID1 = RHM_OPERATORS.OPERATOR_ID
INNER JOIN rhm_repair_type ON rhm_repairs.repair_type = rhm_repair_type.repair_type
INNER JOIN rhm_trades ON rhm_job_seqs.trade_code = rhm_trades.trade_code
INNER JOIN rhm_subareas ON rhm_repairs.subarea_no = rhm_subareas.subarea_no
INNER JOIN rhm_yhn_areas ON rhm_subareas.yhn_area_no = rhm_yhn_areas.area_no 
WHERE
NOT (RHM_REPAIRS.TENANT_ADDRESS1 LIKE '9999Z' OR
RHM_REPAIRS.TENANT_ADDRESS1 LIKE '9999z%' OR
RHM_REPAIRS.TENANT_ADDRESS1 LIKE 'block' OR
RHM_REPAIRS.TENANT_ADDRESS1 LIKE 'Block' OR
RHM_REPAIRS.TENANT_ADDRESS1 LIKE 'Block%' OR
RHM_REPAIRS.TENANT_ADDRESS1 LIKE 'BLOCK')
AND NOT (RHM_REPAIRS.JOB_PRIORITY LIKE 'I' OR RHM_REPAIRS.JOB_PRIORITY LIKE 'V')
AND (RHM_REPAIRS.REPAIR_TYPE LIKE '2' OR
RHM_REPAIRS.REPAIR_TYPE LIKE 'G' OR
RHM_REPAIRS.REPAIR_TYPE LIKE 'S' OR
RHM_REPAIRS.REPAIR_TYPE LIKE 'X')
AND RHM_REPAIRS.TENANT_NAME <> 'VOID'
AND RHM_REPAIRS.TENANT_NAME <> 'Void'
AND RHM_REPAIRS.TENANT_NAME IS NOT NULL
AND RHM_JOB_SEQS.JOB_SEQ_STATUS <> 'X'
AND rhm_repairs.repair_completed BETWEEN SYSDATE-20 AND SYSDATE
AND RHM_REPAIRS.SUBAREA_NO <> '99'
AND rhm_job_seqs.repair_ref IN ('57342819','57257795')
AND rhm_job_seqs.job_seq = '1'
ORDER BY
RHM_JOB_SEQS.REPAIR_REF, rhm_job_seqs.job_seq
  

Ответ №1:

Я бы попробовал row_number()

  select * from (   
SELECT
    rhm_job_seqs.repair_ref AS "Repair Reference",
    rhm_repairs.tenant_name AS "Tenant Name",
    rhm_repairs.tenant_address1 AS "Tenant Address1",
    rhm_repairs.tenant_address2 AS "Tenant Address2",
    rhm_repairs.tenant_postcode AS "Tenant PostCode",
    rhm_job_seqs.job_seq AS "Job Sequence",
    rhm_trades.trade_code AS "Trade Code",
    rhm_trades.trade_desc AS "Trade",
    row_number() over (partition by rhm_job_seqs.repair_ref order by  rhm_job_seqs.repair_ref, rhm_job_seqs.job_seq) r
    FROM (
    RHM_REPAIRS
    INNER JOIN RHM_JOB_SEQS ON RHM_REPAIRS.REPAIR_REF = RHM_JOB_SEQS.REPAIR_REF)
    INNER JOIN RHM_OPERATORS ON RHM_JOB_SEQS.OPERATOR_ID1 = RHM_OPERATORS.OPERATOR_ID
    INNER JOIN rhm_repair_type ON rhm_repairs.repair_type = rhm_repair_type.repair_type
    INNER JOIN rhm_trades ON rhm_job_seqs.trade_code = rhm_trades.trade_code
    INNER JOIN rhm_subareas ON rhm_repairs.subarea_no = rhm_subareas.subarea_no
    INNER JOIN rhm_yhn_areas ON rhm_subareas.yhn_area_no = rhm_yhn_areas.area_no 
    WHERE
    NOT (RHM_REPAIRS.TENANT_ADDRESS1 LIKE '9999Z' OR
    RHM_REPAIRS.TENANT_ADDRESS1 LIKE '9999z%' OR
    RHM_REPAIRS.TENANT_ADDRESS1 LIKE 'block' OR
    RHM_REPAIRS.TENANT_ADDRESS1 LIKE 'Block' OR
    RHM_REPAIRS.TENANT_ADDRESS1 LIKE 'Block%' OR
    RHM_REPAIRS.TENANT_ADDRESS1 LIKE 'BLOCK')
    AND NOT (RHM_REPAIRS.JOB_PRIORITY LIKE 'I' OR RHM_REPAIRS.JOB_PRIORITY LIKE 'V')
    AND (RHM_REPAIRS.REPAIR_TYPE LIKE '2' OR
    RHM_REPAIRS.REPAIR_TYPE LIKE 'G' OR
    RHM_REPAIRS.REPAIR_TYPE LIKE 'S' OR
    RHM_REPAIRS.REPAIR_TYPE LIKE 'X')
    AND RHM_REPAIRS.TENANT_NAME <> 'VOID'
    AND RHM_REPAIRS.TENANT_NAME <> 'Void'
    AND RHM_REPAIRS.TENANT_NAME IS NOT NULL
    AND RHM_JOB_SEQS.JOB_SEQ_STATUS <> 'X'
    AND rhm_repairs.repair_completed BETWEEN SYSDATE-20 AND SYSDATE
    AND RHM_REPAIRS.SUBAREA_NO <> '99'
    AND rhm_job_seqs.repair_ref IN ('57342819','57257795')
    AND rhm_job_seqs.job_seq = '1'
) where r = 1
    ORDER BY
    "Repair Reference", "Job Sequence"
  

Ответ №2:

Это может сработать — в основном для каждой строки я бы спросил, существуют ли какие-то более высокие последовательности заданий:

 SELECT
    rhm_job_seqs.repair_ref AS "Repair Reference",
    rhm_repairs.tenant_name AS "Tenant Name",
    rhm_repairs.tenant_address1 AS "Tenant Address1",
    rhm_repairs.tenant_address2 AS "Tenant Address2",
    rhm_repairs.tenant_postcode AS "Tenant PostCode",
    rhm_job_seqs.job_seq AS "Job Sequence",
    rhm_trades.trade_code AS "Trade Code",
    CASE WHEN EXISTS (
        SELECT *
        FROM RHM_JOB_SEQS job_seqs2
        WHERE rhm_job_seqs.repair_ref = job_seqs2.repair_ref
            AND rhm_job_seqs.trade_code <> job_seqs2.trade_code
            AND job_seqs2.job_seq > 1
    )
    THEN 'Multi Trade'
    ELSE rhm_trades.trade_desc
    END AS "Trade"
FROM RHM_REPAIRS
INNER JOIN RHM_JOB_SEQS ON RHM_REPAIRS.REPAIR_REF = RHM_JOB_SEQS.REPAIR_REF
INNER JOIN RHM_OPERATORS ON RHM_JOB_SEQS.OPERATOR_ID1 = RHM_OPERATORS.OPERATOR_ID
INNER JOIN rhm_repair_type ON rhm_repairs.repair_type = rhm_repair_type.repair_type
INNER JOIN rhm_trades ON rhm_job_seqs.trade_code = rhm_trades.trade_code
INNER JOIN rhm_subareas ON rhm_repairs.subarea_no = rhm_subareas.subarea_no
INNER JOIN rhm_yhn_areas ON rhm_subareas.yhn_area_no = rhm_yhn_areas.area_no 
WHERE
    NOT (
        RHM_REPAIRS.TENANT_ADDRESS1 LIKE '9999Z' OR
        RHM_REPAIRS.TENANT_ADDRESS1 LIKE '9999z%' OR
        RHM_REPAIRS.TENANT_ADDRESS1 LIKE 'block' OR
        /** RHM_REPAIRS.TENANT_ADDRESS1 LIKE 'Block' OR **/
        RHM_REPAIRS.TENANT_ADDRESS1 LIKE 'Block%' OR
        RHM_REPAIRS.TENANT_ADDRESS1 LIKE 'BLOCK'
    )
    AND NOT (RHM_REPAIRS.JOB_PRIORITY LIKE 'I' OR RHM_REPAIRS.JOB_PRIORITY LIKE 'V')
    AND (
        RHM_REPAIRS.REPAIR_TYPE LIKE '2' OR
        RHM_REPAIRS.REPAIR_TYPE LIKE 'G' OR
        RHM_REPAIRS.REPAIR_TYPE LIKE 'S' OR
        RHM_REPAIRS.REPAIR_TYPE LIKE 'X'
    )
    AND RHM_REPAIRS.TENANT_NAME <> 'VOID'
    AND RHM_REPAIRS.TENANT_NAME <> 'Void'
    AND RHM_REPAIRS.TENANT_NAME IS NOT NULL
    AND RHM_JOB_SEQS.JOB_SEQ_STATUS <> 'X'
    AND rhm_repairs.repair_completed BETWEEN SYSDATE-20 AND SYSDATE
    AND RHM_REPAIRS.SUBAREA_NO <> '99'
    AND rhm_job_seqs.repair_ref IN ('57342819','57257795')
    AND rhm_job_seqs.job_seq = '1'
ORDER BY RHM_JOB_SEQS.REPAIR_REF, rhm_job_seqs.job_seq
  

Я также прокомментировал бесполезное условие.

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

1. Привет, спасибо за ваш ответ на мой вопрос — очень признателен. Похоже, это то, что мне нужно. Решение почти дало мне то, что я хотел, но я добавил ‘и rhm_job_seqs.trade_code <> job_seqs2.trade_code’ между ГДЕ rhm_job_seqs.repair_ref = job_seqs2.repair_ref И job_seqs2.job_seq> 1, и это дало мне нужные результаты. Я несколько дней отсутствовал в офисе, отсюда и мой поздний ответ, но большое спасибо за то, что вы помогли мне разобраться в моем запросе / извлечении данных.