Оставлено соединение на подстроке по сравнению с номером в Oracle - PullRequest
0 голосов
/ 25 июня 2019

Я использую Oracle 11g Enterprise Edition Release 11.2.0.4.0 и хочу объединить две таблицы в подстроке одного из столбцов.(см., например, http://sqlfiddle.com/#!9/8955c8/8)

Таблица 1 - DW_PCS:

DESC DW_PCS

Result:
PAYEE_ID      VARCHAR2
ACCOUNT_NB    VARCHAR2

Таблица 2 - DW_CLAIM:

DESC DW_CLAIM

Result:
CLAIM_ID      VARCHAR2
CLAIMANT_ID   NUMBER

SUBSTR(DW_PCS.PAYEE_ID, 2, 7) является псевдонимом для CLAIMANT_ID, поэтому я попробовал следующее, которое прекрасно работает в MySQL (см. http://sqlfiddle.com/#!9/8955c8/8):

SELECT 
  DW_PCS.PAYEE_ID, 
  SUBSTR(DW_PCS.PAYEE_ID, 2, 7) AS CLAIMANT_ID, 
  DW_PCS.ACCOUNT_NB,
  DW_CLAIM.CLAIM_ID 
FROM 
  DW_PCS 
  LEFT JOIN DWH.DW_CLAIM ON 
  SUBSTR(DW_PCS.PAYEE_ID, 2, 7) = DW_CLAIM.CLAIMANT_ID

Но это выдает ошибку ORA-12801 / ORA-01722, которая, очевидно, означает, что яЯ не использую правильные типы данных в моем сравнении.

Теперь, если я изменю условие на SUBSTR(DW_PCS.PAYEE_ID, 2, 7) = TO_CHAR(DW_CLAIM.CLAIMANT_ID), оно будет работать, если PAYEE_ID не будет чем-то вроде C0152426. Начальные нули становятся проблематичными из-заDW_CLAIM.CLAIMANT_ID - это число. Как мне сделать этот запрос в Oracle?

Ответы [ 3 ]

1 голос
/ 25 июня 2019

Я думаю, что у вас есть некоторые "поврежденные" данные, где SUBSTR(d.PAYEE_ID, 2, 7) не является числовым.Вы можете идентифицировать их, используя REGEXP_LIKE, например: WHERE REGEXP_LIKE(SUBSTR(d.PAYEE_ID, 2, 7), '\D').

Тогда вы сами выбираете, как поступить с этими данными.Одна из возможностей - использовать case в условии JOIN и только JOIN, когда SUBSTR (d.PAYEE_ID, 2, 7) является числовым:

SELECT
    d.PAYEE_ID,
    SUBSTR(d.PAYEE_ID, 2, 7) AS CLAIMANT_ID,
    d.ACCOUNT_NB,
    c.CLAIM_ID
FROM DW_PCS d
LEFT JOIN DW_CLAIM c
  ON c.CLAIMANT_ID = CASE WHEN NOT REGEXP_LIKE(SUBSTR(d.PAYEE_ID, 2, 7),'\D') 
                          THEN TO_NUMBER(SUBSTR(d.PAYEE_ID, 2, 7))
                     END

PS: я думаю, что MySQL преобразует обе стороны в строки для сравнения, тогда какOracle пытается преобразовать левую сторону в число, которое приводит к этой ошибке.Поэтому разница ...

0 голосов
/ 25 июня 2019

это выдает ошибку [] ORA-01722, которая, по-видимому, означает, что я не использую правильные типы данных в моем сравнении.

Нет, ORA-01722 - ошибка неверного номера. Это означает, что Oracle неявно пытается преобразовать значения в один и тот же тип данных и преобразует SUBSTR(DW_PCS.PAYEE_ID, 2, 7) в число, но по крайней мере одна из строк имеет нечисловые значения в этой подстроке, и преобразование завершается неудачей.

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

SELECT *
FROM   DW_PCS
WHERE  NOT REGEXP_LIKE( SUBSTR(PAYEE_ID, 2, 7), '^\d+$' )

Начальные нули становятся проблематичными из-за того, что DW_CLAIM.CLAIMANT_ID является числом. Как мне сделать этот запрос в Oracle?

Вы можете решить свою проблему, заполнив нулями начало CLAIMANT_ID при преобразовании его в строку:

SELECT 
  DW_PCS.PAYEE_ID, 
  SUBSTR(DW_PCS.PAYEE_ID, 2, 7) AS CLAIMANT_ID, 
  DW_PCS.ACCOUNT_NB,
  DW_CLAIM.CLAIM_ID 
FROM 
  DW_PCS 
  LEFT JOIN DWH.DW_CLAIM ON 
  SUBSTR(DW_PCS.PAYEE_ID, 2, 7) = TO_CHAR( DW_CLAIM.CLAIMANT_ID, 'fm0000000' )
0 голосов
/ 25 июня 2019

Попробуйте привести подстроку PAYEE_ID к числу:

SELECT
    d.PAYEE_ID,
    SUBSTR(d.PAYEE_ID, 2) AS CLAIMANT_ID,
    d.ACCOUNT_NB,
    dc.CLAIM_ID
FROM DW_PCS d
LEFT JOIN DWH.DW_CLAIM dc
    ON TO_NUMBER(SUBSTR(d.PAYEE_ID, 2)) = c.CLAIMANT_ID;

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

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