2016-08-16 2 views
0

После многого изучения большого количества синтаксиса SQL я все еще недостаточно.SQL Cases Group By the Pivots Агрегаты головной боли

У меня есть таблица, где данные хранятся как таковой:

LineNumber  Date   JobNumber  Task   Hours 
------------------------------------------------------------------ 
1    2016-08-15  100   Task 1   0.5 
1    2016-08-16  100   Task 1   2.0 
2    2016-08-15  200   Task 2   4.0 
3    2016-08-16  200   Task 3   1.5 
4    2016-08-17  200   Task 6   3.5 

То, что я после выполнения форматирования результатов, так как они выглядят следующим образом:

LineNumber  JobNumber  Task  Monday  Tuesday Wednesday 
-------------------------------------------------------------------------- 
1    100    Task 1  0.5  2.0   0.0 
2    200    Task 2  4.0  0.0   0.0 
3    200    Task 3  0.0  1.5   0.0 
4    200    Task 6  0.0  0.0   3.5 

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

Используя это:

DECLARE @UserID int; 
DECLARE @StartDate date; 
DECLARE @MondayDate date; 
DECLARE @TuesdayDate date; 
DECLARE @WednesdayDate date; 
DECLARE @ThursdayDate date; 
DECLARE @FridayDate date; 
DECLARE @SaturdayDate date; 
DECLARE @SundayDate date; 

SET @UserID = '1'; 
SET @StartDate = '2016-08-15'; 
SET @MondayDate = @StartDate; 
SET @TuesdayDate = DATEADD(DAY, 1, @StartDate); 
SET @WednesdayDate = DATEADD(DAY, 2, @StartDate); 
SET @ThursdayDate = DATEADD(DAY, 3, @StartDate); 
SET @FridayDate = DATEADD(DAY, 4, @StartDate); 
SET @SaturdayDate = DATEADD(DAY, 5, @StartDate); 
SET @SundayDate = DATEADD(DAY, 6, @StartDate); 

select LineNumber, JobNumber, JobName, Task, 
Monday = (CASE WHEN Date = @MondayDate THEN Hours ELSE '0.0' END), 
Tuesday = (CASE WHEN Date = @TuesdayDate THEN Hours ELSE '0.0' END), 
Wednesday = (CASE WHEN Date = @WednesdayDate THEN Hours ELSE '0.0' END), 
Thursday = (CASE WHEN Date = @ThursdayDate THEN Hours ELSE '0.0' END), 
Friday = (CASE WHEN Date = @FridayDate THEN Hours ELSE '0.0' END), 
Saturday = (CASE WHEN Date = @SaturdayDate THEN Hours ELSE '0.0' END), 
Sunday = (CASE WHEN Date = @SundayDate THEN Hours ELSE '0.0' END) 

From v_TimesheetDataLines 

WHERE Date >= @MondayDate and Date <= @SundayDate and UserID = @UserID 
Order By LineNumber asc 

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

Мои результаты в настоящее время, как это:

LineNumber  JobNumber  Task  Monday  Tuesday Wednesday 
-------------------------------------------------------------------------- 
1    100    Task 1  0.5  0.0  0.0 
1    100    Task 1  0.0  2.0  0.0 
2    200    Task 2  4.0  0.0  0.0 
3    200    Task 3  0.0  1.5  0.0 
4    200    Task 6  0.0  0.0  3.5 

Так сво 2 линии, которые являются одновременно быть строка 1 в конечных результатах, что мне нужно группе. Они всегда будут иметь одинаковый номер и задание.

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

Любые ответы \ help очень ценятся как всегда.

+0

Пожалуйста, покажите ожидаемый выход – TheGameiswar

+0

Hi игры, второй блок кода показывает, что я после выхода. В основном, он должен группироваться с помощью LineNumber, JobNumber и Task. – DA082

ответ

0

Используйте GROUP BY over LineNumber, JobNumber и Task. Используйте MAX (или SUM) в будние дни.

Edit:

Как this

+0

Привет Энди, используя агрегат в будние дни, означает, что я получаю только самую большую, минимальную или сумму столбца часов. Мне нужно, чтобы значения оставались такими, какие они есть. – DA082

+0

@ DA082 - это только совокупность значений, если бы они были на одной и той же задаче, в тот же день. Я предположил, что ваше желаемое поведение было 1 строка за задание. http://sqlfiddle.com/#!9/51755/2 –

0

Для вашего рассмотрения:

Просто примечание стороны, Вы могли бы добавить UserID в группе с помощью параметра и сделать все в одном кадре.

Exec [prc-Pivot] 'Select * from YourData','DateName(WEEKDAY,Date)','sum(Hours)[]','LineNumber,JobNumber','count(*)[Records]' 

Возвращает

LineNumber JobNumber Records Monday Tuesday Wednesday 
1   100   2  0.50  2.00  0.00 
2   200   1  4.00  0.00  0.00 
3   200   1  0.00  1.50  0.00 
4   200   1  0.00  0.00  3.50 

хранимая процедура для динамического Повороты

CREATE PROCEDURE [dbo].[prc-Pivot] (
    @Source varchar(1000),   -- Any Table or Select Statement 
    @PvotCol varchar(250),   -- Field name or expression ie. Month(Date) 
    @Summaries varchar(250),  -- aggfunction(aggValue)[optionalTitle] 
    @GroupBy varchar(250),   -- Optional additional Group By 
    @OtherCols varchar(500))  -- Optional Group By or aggregates 
AS 

--Exec [prc-Pivot] 'Select Year=Year(TR_Date),* From [Chinrus-Series].[dbo].[DS_Treasury_Rates]','''Q''+DateName(QQ,TR_Date)','avg(TR_Y10)[-Avg]','Year','count(*)[Records],min(TR_Y10)[Min],max(TR_Y10)[Max],Avg(TR_Y10)[Avg]' 
--Exec [prc-Pivot] '#Temp','Attribute','max(Description)[]','ID','count(*)[Records]' 

Set NoCount On 

Declare @Vals varchar(max),@SQL varchar(max); 
Set @Vals = '' 
Set @OtherCols= IsNull(', ' + @OtherCols,'') 
Set @Source = case when @Source Like 'Select%' then @Source else 'Select * From '[email protected] end 
Create Table #TempPvot (Pvot varchar(100)) 
Insert Into #TempPvot 
Exec ('Select Distinct Convert(varchar(100),' + @PvotCol + ') as Pvot FROM (' + @Source + ') A') 
Select @Vals = @Vals + ', isnull(' + Replace(Replace(@Summaries,'(','(CASE WHEN ' + @PvotCol + '=''' + Pvot + ''' THEN '),')[', ' END),0) As [' + Pvot) From #TempPvot Order by Pvot 
Drop Table #TempPvot 
Set @SQL = Replace('Select ' + Isnull(@GroupBy,'') + @OtherCols + @Vals + ' From (' + @Source + ') PvtFinal ' + case when Isnull(@GroupBy,'')<>'' then 'Group By ' + @GroupBy + ' Order by ' + @GroupBy else '' end,'Select , ','Select ') 
--Print @SQL 
Exec (@SQL) 

**

Edit- Для добавления параметров

**

Declare @MondayDate Date = '2016-08-15' 
Declare @SundayDate Date = '2016-08-21' 
Declare @UserID int = 1 
Declare @SQL varchar(max) = 'Select * from YourTable Where Date>='''+cast(@MondayDate as varchar(10))+''' and Date<='''+cast(@SundayDate as varchar(10))+''' and UserID='+cast(@UserID as varchar(25)) 

Exec [prc-Pivot] @SQL,'DateName(WEEKDAY,Date)','sum(Hours)[]','LineNumber,JobNumber','count(*)[Records]' 

Не какая версия SQL Server точно, но Concat был бы мой выбор при построении SQL строки

+0

Привет, Джон, это почти работает, за исключением того, что мне нужно указать диапазон дат как часть оператора select. Когда я это делаю, я получаю сообщение об ошибке «Операнд типа clash: дата несовместима с int» – DA082

+0

@ DA082 обновленный ответ - см. EDIT внизу –