Если а затем б проверить, где пункт - PullRequest
0 голосов
/ 23 февраля 2019

Я выполняю некоторые проверки качества данных для выявления неверных данных, я не могу понять, как я могу выполнить проверку, чтобы данные были точно сопоставлены на основе значения 1 против значения 2.

Iв конечном счете необходимо идентифицировать все идентификаторы в T1, которые имеют неправильное отображение в T2. Я использовал следующий код, но, похоже, не дает желаемого результата.Сопоставление отсутствует в базе данных и является правилом, на основе которого необходимо вводить данные.
- Когда значение указано в: яблоки, бананы, вишня, груши, киви - тогда оно должно быть сопоставлено с фруктами
-когда значение в: сыр - затем сыр
- когда значение в: кешью, миндаль - затем орехи
- когда значение в: кегли - тогда конфеты
- когда значение в: шоколад - то ноль

Редактировать: я добавил нужный вывод.

SELECT t1.id, t2.*
FROM t1,t2,t3
WHERE 
    t1.id = t2.id
    AND (
        (t2.value1_id IN (01,04,05,08,09) AND t2.value2_id <> 2)
        OR (t2.value1_id = 02 and t2.value2_id <> 3)
        OR (t2.value1_id IN (03,10) and t2.value2_id <> 1)
        OR (t2.value1_id = 06 AND t2.value2_id <> 4)
        OR (t2.value1_id = 07 AND t2.value_id IS NOT NULL)
    )

T1

ID     
1    
2    
3 
4 
5   
6
7

T2

T1.ID Value1_ID Value2_ID    
1       01        2     
1       02        3     
1       03        1    
2       04        2    
2       05        2    
2       02        3    
2       06        4    
2       07             
3       08        2    
3       02        3    
4       09        2    
4       10        1    
5       02        2
5       10        1
6       04        3
6       10        2
7       07        2

T3

ID   Value1     
01   Apples    
02   Cheese    
03   Cashews    
04   Bananas    
05   Cherries    
06   Skittles    
07   Chocolate    
08   Pears    
09   Kiwis    
10   Almonds    

T4

ID  Value2    
1    Nuts    
2    Fruit    
3    Cheese    
4    Candy    

Требуемый выход:

T1.ID Value1_ID Value2_ID    
5       02            2
6       04            3    
6       10            2     
7       07            2   
  • T1.ID 5, значение1_id 02 находится в желаемом выходе, поскольку сыр отображается на фрукты
  • T1.ID 6, value1_id 04 - Бананы сопоставляются с сыром
  • T1.ID 6, value1_id 10 - Миндаль сопоставляется с фруктами
  • T1.ID 7, value1_id 07 - Шоколад сопоставляется с фруктамикогда он должен быть нулевым

Ответы [ 3 ]

0 голосов
/ 25 февраля 2019

Я настоятельно рекомендую вам создать таблицу для представления отношения один-ко-многим между T4 и T3.Это стало бы первым шагом к исправлению вашего проекта, предоставляя простой способ решения вашего текущего вопроса.

Вот заказ CREATE TABLE ... AS SELECT, который инициализирует такую ​​таблицу с вашими примерами данных:

create table cat AS
SELECT 1 t3_id, 2 t4_id FROM DUAL
UNION ALL SELECT 4, 2 FROM DUAL
UNION ALL SELECT 5, 2 FROM DUAL
UNION ALL SELECT 8, 2 FROM DUAL
UNION ALL SELECT 9, 2 FROM DUAL
UNION ALL SELECT 2, 3 FROM DUAL
UNION ALL SELECT 3, 1 FROM DUAL
UNION ALL SELECT 10, 1 FROM DUAL
UNION ALL SELECT 6, 4 FROM DUAL
UNION ALL SELECT 7, NULL FROM DUAL
;

С этой таблицей определение неправильно сопоставленных записей так же просто, как:

SELECT t2.*
FROM t2
WHERE t2.Value2_ID IS NOT NULL AND NOT EXISTS (
    SELECT 1 FROM cat WHERE cat.t3_id = t2.Value1_ID AND cat.t4_id = t2.Value2_ID
)

Это Демонстрация DB Fiddle с примерами данных:

T1_ID | VALUE1_ID | VALUE2_ID
----: | --------: | --------:
    5 |         2 |         2
    6 |         4 |         3
    6 |        10 |         2
    7 |         7 |         2

Подсказка для дальнейшего улучшения вашего дизайна: у вас есть отношение один ко многим между T4 (семейства алиментов) и T3 (алименты).Классический способ представить это - добавить столбец в дочернюю таблицу (T3), который ссылается на родительскую таблицу.

0 голосов
/ 26 февраля 2019

Если вы не можете создать таблицу с сопоставлениями из фруктов в категории и знаете, что значения являются статическими, просто включите сопоставления в ваш запрос, используя вложенный подзапрос или условие факторинга подзапроса:

Установка Oracle :

create table T2 ( id, value1_id, value2_id ) as
select 1, '01', 2 from dual union all
select 1, '02', 3 from dual union all
select 1, '03', 1 from dual union all
select 2, '04', 2 from dual union all
select 2, '05', 2 from dual union all
select 2, '02', 3 from dual union all
select 2, '06', 4 from dual union all
select 2, '07', null  from dual union all
select 3, '08', 2 from dual union all
select 3, '02', 3 from dual union all
select 4, '09', 2 from dual union all
select 4, '10', 1 from dual union all
select 5, '02', 2 from dual union all
select 5, '10', 1 from dual union all
select 6, '04', 3 from dual union all
select 6, '10', 2 from dual union all
select 7, '07', 2 from dual;

Запрос :

WITH mappings ( name, category ) AS (
  SELECT '01', 2 FROM DUAL UNION ALL
  SELECT '02', 3 FROM DUAL UNION ALL
  SELECT '03', 1 FROM DUAL UNION ALL
  SELECT '04', 2 FROM DUAL UNION ALL
  SELECT '05', 2 FROM DUAL UNION ALL
  SELECT '06', 4 FROM DUAL UNION ALL
  SELECT '07', NULL FROM DUAL UNION ALL
  SELECT '08', 2 FROM DUAL UNION ALL
  SELECT '09', 2 FROM DUAL UNION ALL
  SELECT '10', 1 FROM DUAL
)
SELECT *
FROM   T2 t
WHERE  NOT EXISTS (
  SELECT 1
  FROM   mappings m
  WHERE  t.value1_id = m.name
  AND    (  t.value2_id = m.category
         OR ( t.value2_id IS NULL AND m.category IS NULL ) )
);

Результаты :

ID | VALUE1_ID | VALUE2_ID
-: | :-------- | --------:
 5 | 02        |         2
 6 | 04        |         3
 6 | 10        |         2
 7 | 07        |         2

дБ <> скрипка здесь

0 голосов
/ 24 февраля 2019

Одна из проблем заключается в том, что, глядя на T2, нелегко определить, является ли «отображение» правильным или нет.При создании тестовых данных для T1 и T2 мы использовали CHAR для VALUE1_ID, чтобы сделать последующие запросы более «читабельными».

Таблицы

create table T1( id primary key ) 
as
select 1 from dual union all
select 2 from dual union all
select 3 from dual ;


create table T2 ( id, value1_id, value2_id )
as
select 1, '01', 2 from dual union all
select 1, '02', 3 from dual union all
select 1, '03', 1 from dual union all
select 2, '04', 2 from dual union all
select 2, '05', 2 from dual union all
select 2, '02', 3 from dual union all
select 2, '06', 4 from dual union all
select 2, '07', null  from dual union all
select 3, '08', 2 from dual union all
select 3, '02', 3 from dual union all
select 4, '09', 2 from dual union all
select 4, '10', 1 from dual ;

Реорганизованный запрос

--
-- find incorrect mappings 
--
select t2.*, 'T1 id not valid' as status
from t2
where t2.id not in ( select id from T1 )
union all
select t2.*, 'value1_id <-> value2_id mapping incorrect '
from t1 join t2 on t1.id = t2.id
where
    ( t2.value1_id in ('01','04','05','08','09') and t2.value2_id <> 2 )
    or
    ( t2.value1_id = '02' and t2.value2_id <> 3 )
    or
    ( t2.value1_id in ('03','10') and t2.value2_id <> 1 )
    or
    ( t2.value1_id = '06' and t2.value2_id <> 4 )
    or
    ( t2.value1_id = '07' and t2.value2_id is null )
;

-- result
ID  VALUE1_ID  VALUE2_ID  STATUS                                      
4   10         1          T1 id not valid                             
4   09         2          T1 id not valid                             
2   07         NULL       value1_id <-> value2_id mapping incorrect 

DBfiddle

ALTERNATIVE

Другая возможность может бытьСоздайте таблицу, содержащую все допустимые сопоставления, в «удобочитаемой» форме и используйте ее для проверки сопоставлений, хранящихся в T2.Тем не менее, используйте любой подход, который вам удобнее - при условии, что вы получите правильные результаты.Пример (проверено с Oracle 12c, 18c)

-- in addition to tables T1, T2, T3, and T4: table with correct mappings
create table map( category, product )
as
select 'Fruit', 'Apples' from dual union all
select 'Cheese', 'Cheese' from dual union all
select 'Nuts', 'Cashews' from dual union all
select 'Fruit', 'Bananas' from dual union all
select 'Fruit', 'Cherries' from dual union all
select 'Candy', 'Skittles' from dual union all
select 'Candy', 'Chocolate' from dual union all
select 'Fruit', 'Pears' from dual union all
select 'Fruit', 'Kiwis' from dual union all
select 'Nuts', 'Almonds' from dual;

-- make sure that the entries in the MAP table tie in with T3 and T4
alter table map 
add (
  constraint m_pk primary key ( category, product )
, constraint m_category_fk foreign key ( category ) references T4 ( value2 )
, constraint m_product_fk foreign key ( product ) references T3 ( value1 )
) ;

Найти неправильные сопоставления

-- T2 rows containing incorrect (invalid) mappings
--   -> all rows MINUS the correct ones
select T2.id, T2.value1_id, T2.value2_id
from T2
minus (
  select T2.id, T2.value1_id, T2.value2_id
  from T2
    join (
  --
    select T4.id categoryid, T3.id productid, M.category, M.product
    from T4
      join map M on T4.value2 = M.category
      join T3    on T3.value1 = M.product
  --
  ) C -- correct mappings
    on 
      C.productid = T2.value1_id
  and C.categoryid = T2.value2_id
) ;

-- result
ID  VALUE1_ID  VALUE2_ID  
2   07         NULL 

DBfiddle

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...