Подзапрос с TOP 1 возвращает более одной строки в Oracle NetSuite - PullRequest
0 голосов
/ 30 января 2019

Подзапрос возвращает более одной строки, несмотря на использование TOP 1.

Большую часть своей жизни я работал с MS SQL, и я уверен, что следующий код будет работать, но в Oracle (NetSuite) он не работает.

Я пытаюсь объединить строки из таблицы TRANSACTIONS со строками из таблицы SYSTEM_NOTES, используя столбец TRANSACTION_ID таким образом, что для каждой строки в TRANSACTIONS должна быть возвращена только одна строка из SYSTEM_NOTES.

В таблице SYSTEM_NOTES может не быть ни одной, ни одной, ни нескольких строк с идентификатором TRANSACTION_ID, совпадающим с идентификатором из таблицы TRANSACTION.

Запрос должен возвращать только самую последнюю строку (определенную на основе столбца DATE_CREATED в таблице SYSTEM_NOTES).

SELECT 
    SS.NAME AS "ENTITY NAME", 
    TL.TRANSACTION_ID AS "TRANSACTION INTERNAL ID", 
    WF.VALUE_NEW AS "APPROVED BY",
    WF.DATE_CREATED AS "APPROVED DATE",
    TL.AMOUNT AS "AMOUNT (entity currency)",
    (CASE WHEN TL.AMOUNT_FOREIGN IS NULL THEN TL.AMOUNT ELSE TL.AMOUNT_FOREIGN END) AS "AMOUNT (original currency)",
    CY.SYMBOL AS "CURRENCY CODE"
FROM TRANSACTIONS TS
LEFT OUTER JOIN ACCOUNTS AC ON TL.ACCOUNT_ID  = AC.ACCOUNT_ID
LEFT OUTER JOIN ACCOUNTING_PERIODS AP ON TS.ACCOUNTING_PERIOD_ID = AP.ACCOUNTING_PERIOD_ID
LEFT OUTER JOIN 

/* The following part for some entries returns more than one row despite using TOP 1 */

(SELECT TOP 1 SN.TRANSACTION_ID, SN.VALUE_NEW, SN.DATE_CREATED FROM SYSTEM_NOTES SN WHERE SN.STANDARD_FIELD = 'NEXTAPPROVER' AND SN.VALUE_NEW IS NOT NULL
ORDER BY SN.DATE_CREATED DESC) 
WF ON WF.TRANSACTION_ID = TS.TRANSACTION_ID
/* End of the faulty part */

WHERE TL.AMOUNT IS NOT NULL AND TL.AMOUNT <> 0
AND TS.IS_NON_POSTING = N'No'
AND (AP.QUARTER = N'No' AND AP.YEAR_0 = N'No' AND CAST(AP.STARTING AS DATE) BETWEEN {d '2018-12-01'} AND {d '2018-12-01'})

Когда я запускаю подзапрос только для одного идентификатора транзакции, я получаю только 1строка, как и ожидалось (в таблице SYSTEM_NOTES есть три записи с этим идентификатором).

SELECT TOP 1 
SN.TRANSACTION_ID, 
SN.VALUE_NEW, SN.DATE_CREATED FROM SYSTEM_NOTES SN WHERE SN.STANDARD_FIELD = 'NEXTAPPROVER' AND SN.VALUE_NEW IS NOT NULL AND SN.TRANSACTION_ID = 171954
    ORDER BY SN.DATE_CREATED DESC

Я также попробовал следующий код, но часть row_number (), похоже, не работает в моей системе.

SELECT SN.TRANSACTION_ID, SN.VALUE_NEW, SN.DATE_CREATED,
ROW_NUMBER() OVER (ORDER BY SN.DATE_CREATED DESC ) AS ROW_NUM
 FROM SYSTEM_NOTES SN 
WHERE SN.STANDARD_FIELD = 'NEXTAPPROVER' AND SN.VALUE_NEW IS NOT NULL
AND SN.TRANSACTION_ID = 171954

1 Ответ

0 голосов
/ 31 января 2019

Я думаю, вы должны использовать rownum вместо TOP.

Синтаксис:

 select * from dual where /*conditions*/ and rownum = 1

Я сделал для вас пример:

  • с rownum:

Пример - rownum = 1

  • с row_number:

Пример - row_number ()

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