2014-09-03 2 views
0

Я уже давно застрял в этом вопросе. Думаю, я очень близка, но кое-что мне не хватает.Показать только одну запись, которая может или не иметь детей

Сделка может иметь ноль или множество TransactionErrors. Я пытаюсь показать все транзакции только один раз, и я также пытаюсь отобразить только последнее сообщение об ошибке, если оно есть.

SELECT [Transaction].[TransactionID] 
     ,[FileName] 
     ,[DestinationSystem] 
     ,[CreatedOn] 
     ,LEFT([TransactionError].[ErrorMessage], 300) AS LatestErrorMessage --Gets only the first 300 characters of the error message 
FROM [WM01DB].[dbo].[Transaction] 
    INNER JOIN SourceSystem ON SourceSystem.SourceSystemId = Transaction.SourceSystemId 
    LEFT JOIN TransactionError ON TransactionError.TransactionId = Transaction.TransactionId 
WHERE Transaction.CreatedOn >= '2014-08-01 00:00:00.000' 
    AND Transaction.CreatedOn < '2014-09-02 00:00:00.000' 
    ORDER BY [CreatedOn], [Transaction].[TransactionID] 

Когда я запускаю этот запрос, я получаю большую часть результатов, которые я хочу, но я получаю повторяющиеся операции, поскольку эти операции имеют несколько TransactionErrors. Похоже, что это ...

TransactionID  FileName     DestinationSystem CreatedOn   LatestErrorMessage 
18124   201408131541517937_DC_TEST_3339376-4.1.xml TEST   2014-08-18 18:31:19.993  U_BOL and Tracking Number are blank 
18124   201408131541517937_DC_TEST_3339376-4.1.xml TEST   2014-08-18 18:31:19.993  FRT_CHG_TYPE is blank 
18125   201408111521484448_DC_TEST_3339375-2.1.xml TEST   2014-08-19 16:04:58.467  NULL 
18126   201408111521484448_DC_TEST_3339375-2.1.xml TEST   2014-08-19 16:09:00.467  NULL 

тьфу ... недурна блок кода ...

Как вы можете видеть, есть повторяющиеся TransactionIDs, как показано с 18124. Я хотел 18124 отобразить только один раз с последним сообщением об ошибке. Единственный способ получить последнее сообщение об ошибке - использовать последний TransactionErrorID для конкретного транзакционного идентификатора ...

Пожалуйста, помогите! :(

ответ

1

У меня есть подобное решение Krishnraj Рана Однако, я думаю, что вам необходимо избегать наличия фильтра rowid в предложении WHERE, поскольку это будет происходить, если оно будет вести себя как внутреннее соединение:

; with Errors as 
(SELECT [ErrorMessage] 
     , Row_Number() over (Partition By TransactionId order by TransactionErrorId Desc) as id 
    FROM TransactionError 
) 

    SELECT [Transaction].[TransactionID] 
     ,[FileName] 
     ,[DestinationSystem] 
     ,[CreatedOn] 
     ,LEFT([ErrorMessage], 300) AS LatestErrorMessage --Gets only the first 300 characters of the error message 
FROM [WM01DB].[dbo].[Transaction] 
    INNER JOIN SourceSystem ON SourceSystem.SourceSystemId = Transaction.SourceSystemId 
    LEFT JOIN Errors ON TransactionError.TransactionId = Transaction.TransactionId 
     and errors.id = 1 
WHERE Transaction.CreatedOn >= '2014-08-01 00:00:00.000' 
    AND Transaction.CreatedOn < '2014-09-02 00:00:00.000' 
    ORDER BY [CreatedOn], [Transaction].[TransactionID] 
+0

По какой-то причине я не мог запустить этот запрос. –

+0

Я угадал имена столбцов, какую ошибку вы получили? –

+0

Какая бы проблема ни была, это, должно быть, был я. Это, безусловно, лучший способ сделать это. –

1

Вы можете достичь его с помощью ROW_NUMBER() с PARTITION BY пункта, как это -.

SELECT [Transaction].[TransactionID] 
    ,[FileName] 
    ,[DestinationSystem] 
    ,[CreatedOn] 
    ,LEFT([TransactionError].[ErrorMessage], 300) AS LatestErrorMessage --Gets only the first 300 characters of the error message 
    ,ROW_NUMBER() OVER (
     PARTITION BY [Transaction].[TransactionID] ORDER BY [CreatedOn] 
      ,[Transaction].[TransactionID] DESC 
     ) AS SrNo 
FROM [WM01DB].[dbo].[Transaction] 
INNER JOIN SourceSystem ON SourceSystem.SourceSystemId = TRANSACTION.SourceSystemId 
LEFT JOIN TransactionError ON TransactionError.TransactionId = TRANSACTION.TransactionId 
WHERE TRANSACTION.CreatedOn >= '2014-08-01 00:00:00.000' 
    AND TRANSACTION.CreatedOn < '2014-09-02 00:00:00.000' 
    AND SrNo = 1 
ORDER BY [CreatedOn] 
    ,[Transaction].[TransactionID] 
+0

Это 'SrNo' в котором пункт выдаст ошибку, так как это не видно на этот запрос еще, вам нужно используйте это во внешнем запросе. –

1
SELECT A.[TransactionID] 
     ,A.[FileName] 
     ,A.[DestinationSystem] 
     ,A.[CreatedOn] 
     ,A.LatestErrorMessage 
FROM (
SELECT [Transaction].[TransactionID] 
     ,[FileName] 
     ,[DestinationSystem] 
     ,[CreatedOn] 
     ,LEFT([TransactionError].[ErrorMessage], 300) AS LatestErrorMessage --Gets only the first 300 characters of the error message 
     ,ROW_NUMBER() OVER (PARTITION BY [Transaction].[TransactionID] ORDER BY [CreatedOn] DESC) rn 
FROM [WM01DB].[dbo].[Transaction] 
INNER JOIN SourceSystem ON SourceSystem.SourceSystemId = [Transaction].SourceSystemId 
          AND [Transaction].CreatedOn >= '2014-08-01 00:00:00.000' 
          AND [Transaction].CreatedOn < '2014-09-02 00:00:00.000' 
LEFT JOIN TransactionError ON TransactionError.TransactionId = [Transaction].TransactionId 
)A 
WHERE A.rn = 1 
ORDER BY A.[CreatedOn], A.[TransactionID] 
+0

Порядок в разделе partition должен быть 'TransactionErrorId desc' – Laurence

1

используя Также row_number() но выбор последнего TransactionErrorId по просьбе (и при условии, по крайней мере, SQL Server 2005):

with x as (
    select 
     t.[TransactionId], 
     [FileName], 
     [DestinationSytem], 
     [CreatedOn], 
     e.[ErrorMessage], 
     row_number() over (
      partition by t.[TransactionId], 
      order by e.[TransactionErrorId] desc 
     ) rn 
    from 
     [wm01db].[dbo].[Transaction] t 
      inner join 
     [dbo].[SourceSystem] s 
      on t.SourceSystemId = s.SourceSytemId 
      left outer join 
     [dbo].[TransactionError] e 
      on e.TransactionId = t.TransactionId 
    where 
     t.CreatedOn >= '2014-08-01 00:00:00.000' and 
     t.CreatedOn < '2014-09-02 00:00:00.000' 
) select 
    [TransactionId], 
    [FileName], 
    [DestinationSytem], 
    [CreatedOn], 
    left([ErrorMessage], 300) as LastErrorMessage 
from 
    x 
where 
    rn = 1 
order by 
    [CreatedOn], 
    [TransactionId] ; 
+0

К сожалению, это, похоже, не дает мне никаких других результатов, чем мой оригинал. Я все еще вижу дубликаты, которые я показывал раньше. –

+0

К сожалению, пропустили 'where rn = 1' – Laurence

Смежные вопросы