2016-10-24 1 views
1

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

SET @cols = STUFF((SELECT distinct ',' + QUOTENAME([vw_Imported_Files].RF_FileName) 
     FROM [dbo].[vw_Imported_Files] with(nolock) 
     WHERE [vw_Imported_Files].RF_GUID_ID = @sGUID 
AND [vw_Imported_Files].RF_IsEnabled = 1 
     FOR XML PATH(''), TYPE 
     ).value('.', 'NVARCHAR(MAX)') 
    ,1,1,'') 

SET @query2 = 'SELECT ROUND(AVG(CAST(RD_Axis AS FLOAT)),3) AS RD_Axis 
,' + @cols + ' FROM 
(SELECT ROW_NUMBER() OVER (PARTITION BY DenseRank ORDER BY (SELECT NULL)) 
AS RowNumber, rd.* FROM 
    (SELECT DENSE_RANK() OVER (ORDER BY rd.RD_RF_ID) AS DenseRank 
    ,rd.RD_Axis AS RD_Axis 
    ,rd.DN_Values AS DN_Values 
    ,rd.RF_FileName AS RF_FileName 
    FROM #TEMP rd 
    WHERE rd.RD_GUID_ID = ' + @sGUID + ' 
    AND rd.RD_IsEnabled = 1 

) rd 
    ) rn 
    pivot 
     (
      max(DN_Values) 
      for RF_FileName in (' + @cols + ') 
     ) p 
GROUP BY RD_Axis, ' + @cols + ' ' 

execute (@query2) 

На самом деле, этот запрос (@ Query2) результатов, как показано в следующей таблице.

--------------------------------------------------------------- 
| 0  | NULL    | NULL    | 0,996573652935408| 
| 0  | NULL    | 1,00053003751428 | NULL    | 
| 0  | 0,999843071844672 | NULL    | NULL    | 
| 0,052 | NULL    | NULL    | 0,992999630825293| 
| 0,052 | 1,02368347072563 | NULL    | NULL    | 
| 0,053 | NULL    | 0,992674427713489 | NULL    | 
| 0,104 | NULL    | NULL    | 0,998690236570867| 
| 0,104 | NULL    | 0,996645964692132 | NULL    | 
| 0,105 | 0,989815140503533 | NULL    | NULL    | 
---------------------------------------------------------------------------- 

То, что я хочу сделать, чтобы очистить все NULL значения путем группировки Average значений RD_Axis, которые имеют одинаковое значение DENSERANK. В текущем случае DenseRank увеличивается каждые 3 строки. Итак, результат, который я хочу, должен выглядеть так, как показано в следующей таблице.

---------------------------------------------------------------------------- 
| 0  | 0,999843071844672 | 1,00053003751428 | 0,996573652935408| 
| 0,052 | 1,02368347072563  | 0,992674427713489 | 0,992999630825293| 
| 0,104 | 0,989815140503533 | 0,996645964692132 | 0,998690236570867| 
---------------------------------------------------------------------------- 

Надеюсь найти запрос. Не могли бы вы помочь мне разобраться, как преобразовать вышеуказанный код SQL, чтобы получить желаемый результат?

+0

Пожалуйста, объясните, что * вы пытаетесь сделать, а не * как * вы пытались это сделать. Вам не нужны конкатенации строк и XML для поворота, раскрутки или вычисления агрегатов. Без схемы исходного вида невозможно угадать, что задается, или как это можно решить чистым способом. –

ответ

1

Возможно, вам потребуется создать новую переменную столбца, которая получит значение MAX (dynamicColumn) для вашего внешнего выбора .. таким образом вы можете удалить GROUP BY в конце.

SET @cols = STUFF((SELECT distinct ',' + QUOTENAME([vw_Imported_Files].RF_FileName) 
     FROM [dbo].[vw_Imported_Files] with(nolock) 
     WHERE [vw_Imported_Files].RF_GUID_ID = @sGUID 
AND [vw_Imported_Files].RF_IsEnabled = 1 
     FOR XML PATH(''), TYPE 
     ).value('.', 'NVARCHAR(MAX)') 
    ,1,1,'') 

SET @maxCols = STUFF((SELECT distinct ', MAX(' + QUOTENAME([vw_Imported_Files].RF_FileName) + ') AS ' + QUOTENAME([vw_Imported_Files].RF_FileName) 
     FROM [dbo].[vw_Imported_Files] with(nolock) 
     WHERE [vw_Imported_Files].RF_GUID_ID = @sGUID 
AND [vw_Imported_Files].RF_IsEnabled = 1 
     FOR XML PATH(''), TYPE 
     ).value('.', 'NVARCHAR(MAX)') 
    ,1,1,'') 

SET @query2 = ' 
    SELECT ROUND(AVG(CAST(RD_Axis AS FLOAT)),3) AS RD_Axis 
    ,' + @maxCols + ' 
    FROM 
     (SELECT ROW_NUMBER() OVER (PARTITION BY DenseRank ORDER BY (SELECT NULL)) 
       AS RowNumber, rd.* 
     FROM (SELECT DENSE_RANK() OVER (ORDER BY rd.RD_RF_ID) AS DenseRank 
        ,rd.RD_Axis AS RD_Axis 
        ,rd.DN_Values AS DN_Values 
        ,rd.RF_FileName AS RF_FileName 
       FROM #TEMP rd 
       WHERE rd.RD_GUID_ID = ' + @sGUID + ' AND rd.RD_IsEnabled = 1 

      ) rd 
     ) rn 
    pivot 
     (
      max(DN_Values) 
      for RF_FileName in (' + @cols + ') 
     ) p 
    GROUP BY DenseRank' 

execute (@query2) 

Это, вероятно, может быть сделан без использования PIVOT и быть намного ровнее с использованием агрегатов с ДЕЛОМ выражений

+0

код, который вы упомянули, оценивает общее среднее значение столбца RD_Axis и возвращает результат в одной строке. Я хочу группировать «ближе» RD_Axis (между собой - на основе DenseRank) и оценивать их средние значения. Пожалуйста, взгляните на вторую таблицу, которую я создал выше. –

+0

Я не уверен, что это значение выглядит, поскольку вы исключаете его из результатов запроса. Вам может просто понадобиться группировать по этому значению, которое, как я предполагаю, является «RowNumber», или вам может потребоваться выбрать «DenseRank» 'значение также и группу – JamieD77

0

На самом деле я получил результат, который я искал с помощью следующего кода.

SET @cols = STUFF((SELECT distinct ',' + QUOTENAME([vw_Imported_Files].RF_FileName) 
     FROM [dbo].[vw_Imported_Files] with(nolock) 
     WHERE [vw_Imported_Files].RF_GUID_ID = @sGUID and [vw_Imported_Files].RF_IsEnabled = 1 
     FOR XML PATH(''), TYPE 
     ).value('.', 'NVARCHAR(MAX)') 
    ,1,1,'') 

SET @maxCols = STUFF((SELECT distinct ', MAX(' + QUOTENAME([vw_Imported_Files].RF_FileName) + ') AS ' + QUOTENAME([vw_Imported_Files].RF_FileName) 
    FROM [dbo].[vw_Imported_Files] with(nolock) 
    WHERE [vw_Imported_Files].RF_GUID_ID = @sGUID AND [vw_Imported_Files].RF_IsEnabled = 1 
    FOR XML PATH(''), TYPE 
    ).value('.', 'NVARCHAR(MAX)') 
,1,1,'') 

SET @query2 = ' 
SELECT ' + @maxCols + ' 
FROM 
    (SELECT ROW_NUMBER() OVER (PARTITION BY DenseRank ORDER BY (SELECT NULL)) 
      AS RowNumber, rd.* 
    FROM (SELECT DENSE_RANK() OVER (ORDER BY rd.RD_RF_ID) AS DenseRank 
       ,rd.RD_Axis AS RD_Axis 
       ,rd.DN_Values AS DN_Values 
       ,rd.RF_FileName AS RF_FileName 
      FROM #TEMP rd 
      WHERE rd.RD_GUID_ID = ' + @sGUID + ' AND rd.RD_IsEnabled = 1 

     ) rd 
    ) rn 
pivot 
    (
     max(DN_Values) 
     for RF_FileName in (' + @cols + ') 
    ) p 
GROUP BY RowNumber ORDER BY RowNumber' 

execute (@query2) 

Сначала я сгенерировал результат, который я хотел (@ QUERY2), а затем я получил среднее значение RD_Axis с другим запросом (как по заказу ROWNUMBER ASC). Затем я связал их с оператором UNION ALL. Кстати, спасибо за свежий взгляд на мой вопрос, потому что я застрял часами.

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