Разделенная строка не работает должным образом в Oracle SQL - PullRequest
0 голосов
/ 20 марта 2019

Моя таблица:

file_content
MSH|^~\&|LCS|LCA|LIS|TEST9999|199807311532||ORU^R01|3630|P|2.2
PID|3|2161348473|OBRIEN|01572633|20923085580^TESTPAT||19730204|
OBR|1|8642753100013^LIS|20923085580^LCS|083824^PANEL 083824^L|||19980728083600|||||| CH13380|19980728000000||||||20923085580||19980730041800|||F
OBX|1|NM|150001^HIV-1 ABS-O.D. RATIO^L|||||||N|X
OBX|2|CE|001719^HIV-1 ABS, SEMI-QN^L||HTN|||||N|F|19910123|| 19980729155700|BN
OBR|2|8642753100013^LIS|20923085580^LCS|083824^PANEL 083824^L|||19980728083600|||||| CH13380|19980728000000||||||20923085580||19980730041800|||F
OBX|1|NM|150001^HIV-1 ABS-O.D. RATIO^L|||||||N|X
OBX|2|CE|001719^HIV-1 ABS, SEMI-QN^L||HTN|||||N|F|19910123|| 19980729155700|BN

У меня есть следующий запрос SQL, который не работает в приведенном выше случае:

SELECT c.COLUMN_VALUE AS obr_seq, REGEXP_SUBSTR( t.file_content, '^MSH.*?' || CHR(10) || 'PID.*?' || CHR(10) )
         || REGEXP_SUBSTR( t.file_content, 'OBR.*?' || CHR(10) || '((OBX|NTE|FT1).*?($|' || CHR(10) || '))*', 1, c.COLUMN_VALUE ) AS split_value
FROM   test_hl7_message_split t
       LEFT OUTER JOIN
       TABLE(
         CAST(
           MULTISET(
             SELECT LEVEL
             FROM   DUAL
             CONNECT BY LEVEL <= REGEXP_COUNT( t.file_content, 'OBR.*?' || CHR(10) || '((OBX|NTE|FT1).*?($|' || CHR(10) || '))*' )
           ) AS SYS.ODCINUMBERLIST
         )
       ) c
       ON ( 1 = 1 );

Это дает мне неправильный вывод:

OBR_SEQ     SPLIT_VALUE
1           MSH|^~\&|LCS|LCA|LIS|TEST9999|199807311532||ORU^R01|3630|P|2.2
            PID|3|2161348473|OBRIEN|01572633|20923085580^TESTPAT||19730204|
            OBRIEN|01572633|20923085580^TESTPAT||19730204|

2           MSH|^~\&|LCS|LCA|LIS|TEST9999|199807311532||ORU^R01|3630|P|2.2
            PID|3|2161348473|OBRIEN|01572633|20923085580^TESTPAT||19730204|
            OBR|1|8642753100013^LIS|20923085580^LCS|083824^PANEL 083824^L|||19980728083600|||||| CH13380|19980728000000||||||20923085580||19980730041800|||F
            OBX|1|NM|150001^HIV-1 ABS-O.D. RATIO^L|||||||N|X
            OBX|2|CE|001719^HIV-1 ABS, SEMI-QN^L||HTN|||||N|F|19910123|| 19980729155700|BN

3           MSH|^~\&|LCS|LCA|LIS|TEST9999|199807311532||ORU^R01|3630|P|2.2
            PID|3|2161348473|OBRIEN|01572633|20923085580^TESTPAT||19730204|
            OBR|2|8642753100013^LIS|20923085580^LCS|083824^PANEL 083824^L|||19980728083600|||||| CH13380|19980728000000||||||20923085580||19980730041800|||F
            OBX|1|NM|150001^HIV-1 ABS-O.D. RATIO^L|||||||N|X
            OBX|2|CE|001719^HIV-1 ABS, SEMI-QN^L||HTN|||||N|F|19910123|| 19980729155700|BN

Правильный вывод должен быть:

OBR_SEQ     SPLIT_VALUE
1           MSH|^~\&|LCS|LCA|LIS|TEST9999|199807311532||ORU^R01|3630|P|2.2
            PID|3|2161348473|OBRIEN|01572633|20923085580^TESTPAT||19730204|
            OBR|1|8642753100013^LIS|20923085580^LCS|083824^PANEL 083824^L|||19980728083600|||||| CH13380|19980728000000||||||20923085580||19980730041800|||F
            OBX|1|NM|150001^HIV-1 ABS-O.D. RATIO^L|||||||N|X
            OBX|2|CE|001719^HIV-1 ABS, SEMI-QN^L||HTN|||||N|F|19910123|| 19980729155700|BN

2           MSH|^~\&|LCS|LCA|LIS|TEST9999|199807311532||ORU^R01|3630|P|2.2
            PID|3|2161348473|OBRIEN|01572633|20923085580^TESTPAT||19730204|
            OBR|2|8642753100013^LIS|20923085580^LCS|083824^PANEL 083824^L|||19980728083600|||||| CH13380|19980728000000||||||20923085580||19980730041800|||F
            OBX|1|NM|150001^HIV-1 ABS-O.D. RATIO^L|||||||N|X
            OBX|2|CE|001719^HIV-1 ABS, SEMI-QN^L||HTN|||||N|F|19910123|| 19980729155700|BN

По сути, мой скрипт сравнивает OBR в середине сегмента, и я не хочу его.

Может кто-нибудь помочьс этим?

1 Ответ

1 голос
/ 21 марта 2019

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

Настройка Oracle :

CREATE TABLE test_hl7_message_split ( file_content ) AS
SELECT 'MSH|^~\&|LCS|LCA|LIS|TEST9999|199807311532||ORU^R01|3630|P|2.2
PID|3|2161348473|OBRIEN|01572633|20923085580^TESTPAT||19730204|
OBR|1|8642753100013^LIS|20923085580^LCS|083824^PANEL 083824^L|||19980728083600|||||| CH13380|19980728000000||||||20923085580||19980730041800|||F
OBX|1|NM|150001^HIV-1 ABS-O.D. RATIO^L|||||||N|X
OBX|2|CE|001719^HIV-1 ABS, SEMI-QN^L||HTN|||||N|F|19910123|| 19980729155700|BN
OBR|2|8642753100013^LIS|20923085580^LCS|083824^PANEL 083824^L|||19980728083600|||||| CH13380|19980728000000||||||20923085580||19980730041800|||F
OBX|1|NM|150001^HIV-1 ABS-O.D. RATIO^L|||||||N|X
OBX|2|CE|001719^HIV-1 ABS, SEMI-QN^L||HTN|||||N|F|19910123|| 19980729155700|BN' FROM DUAL;

Запрос :

SELECT c.COLUMN_VALUE AS obr_seq,
       head
         || REGEXP_SUBSTR( t.body, 'OBR.*?' || CHR(10) || '((OBX|NTE|FT1).*?($|' || CHR(10) || '))*', 1, c.COLUMN_VALUE ) AS split_value
FROM   ( SELECT REGEXP_SUBSTR( file_content, '^MSH.*?' || CHR(10) || 'PID.*?' || CHR(10) ) AS head,
                REGEXP_REPLACE( file_content, '^MSH.*?' || CHR(10) || 'PID.*?' || CHR(10) ) AS body
         FROM   test_hl7_message_split ) t
       LEFT OUTER JOIN
       TABLE(
         CAST(
           MULTISET(
             SELECT LEVEL
             FROM   DUAL
             CONNECT BY LEVEL <= REGEXP_COUNT( t.body, 'OBR.*?' || CHR(10) || '((OBX|NTE|FT1).*?($|' || CHR(10) || '))*' )
           ) AS SYS.ODCINUMBERLIST
         )
       ) c
       ON ( 1 = 1 );

Вывод :

OBR_SEQ | SPLIT_VALUE                                                                                                                                                                                                                                                                                                                                                                                                                    
------: | :------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
      1 | MSH|^~\&|LCS|LCA|LIS|TEST9999|199807311532||ORU^R01|3630|P|2.2<br>PID|3|2161348473|OBRIEN|01572633|20923085580^TESTPAT||19730204|<br>OBR|1|8642753100013^LIS|20923085580^LCS|083824^PANEL 083824^L|||19980728083600|||||| CH13380|19980728000000||||||20923085580||19980730041800|||F<br>OBX|1|NM|150001^HIV-1 ABS-O.D. RATIO^L|||||||N|X<br>OBX|2|CE|001719^HIV-1 ABS, SEMI-QN^L||HTN|||||N|F|19910123|| 19980729155700|BN<br>
      2 | MSH|^~\&|LCS|LCA|LIS|TEST9999|199807311532||ORU^R01|3630|P|2.2<br>PID|3|2161348473|OBRIEN|01572633|20923085580^TESTPAT||19730204|<br>OBR|2|8642753100013^LIS|20923085580^LCS|083824^PANEL 083824^L|||19980728083600|||||| CH13380|19980728000000||||||20923085580||19980730041800|||F<br>OBX|1|NM|150001^HIV-1 ABS-O.D. RATIO^L|||||||N|X<br>OBX|2|CE|001719^HIV-1 ABS, SEMI-QN^L||HTN|||||N|F|19910123|| 19980729155700|BN    

Запрос 2 :

Другой альтернативой является использование параметра совпадения m в регулярном выражении для обработки строки как нескольких строк, после чего вы можете сопоставить ^OBR, чтобы найти OBR только в начале строки:

SELECT c.COLUMN_VALUE AS obr_seq,
       REGEXP_SUBSTR( t.file_content, '^MSH.*?' || CHR(10) || 'PID.*?' || CHR(10) )
         || REGEXP_SUBSTR( t.file_content, '^OBR.*?' || CHR(10) || '((OBX|NTE|FT1).*?($|' || CHR(10) || '))*', 1, c.COLUMN_VALUE, 'm' ) AS split_value
FROM   test_hl7_message_split t
       LEFT OUTER JOIN
       TABLE(
         CAST(
           MULTISET(
             SELECT LEVEL
             FROM   DUAL
             CONNECT BY LEVEL <= REGEXP_COUNT( t.file_content, '^OBR.*?' || CHR(10) || '((OBX|NTE|FT1).*?($|' || CHR(10) || '))*', 1, 'm' )
           ) AS SYS.ODCINUMBERLIST
         )
       ) c
       ON ( 1 = 1 );

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

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