2016-02-17 5 views
0

У меня сценарий здесь. У меня есть функция, которая правильно вычисляет значение столбца Non_CombinedSet. Условие для этого Non_CombinedSet с использованием case case для группировки и подсчета на основе определенных условий. (Пожалуйста, смотрите коды ниже:..Группирование и суммирование двух разных столбцов на основе разных условий

--Table creation 
CREATE TABLE [dbo].[testrun](
    [ProcessName] [varchar](50) NULL, 
    [ProcessMEMid] [varchar](50) NULL, 
    [ProcessID] [varchar](50) NULL, 
    [ProcessSequence] [varchar](50) NULL, 
    [ProcessSheets] [varchar](50) NULL, 
    [ProcessMABSW] [varchar](50) NULL 
) ON [PRIMARY 

--insert statement 
INSERT INTO [dbo].[testrun] 
      ([ProcessName] 
      ,[ProcessMEMid] 
      ,[ProcessID] 
      ,[ProcessSequence] 
      ,[ProcessSheets] 
      ,[ProcessMABSW]) 

      VALUES 
        ('A1','01-01','X1','1','3','M'), 
        ('B2','01-01','X1','5','2','M'), 
        ('C3','01-02','X1','6','4','M'), 
        ('D4','01-02','X1','10','8','M'), 
        ('E5','01-03','X1','30','18','M'), 
        ('F6','01-03','X1','25','25','M'), 
        ('G7','01-03','X1','50','30','M'), 
        ('H8','01-03','X1','25','15','M'), 
        ('I9','01-04','X1','15','10','M'), 
        ('J10','01-04','X1','15','3','M'), 

        ('K11','01-05','X1','10','2','M'), 

        ('L12','01-05','X1','05','15','M'), 

        ('M13','01-06','X1','05','11','M'), 

        ('N14','01-06','X1','05','13','M'), 

        ('O15','01-01','X1','05','50','M'), 
        ('P16','01-07','X1','05','7','M'), 
        ('Q17','01-07','X1','05','2','S'), 
         ('R18','01-07','X1','05','1','S'), 
         ('S16','01-08','X1','05','7','S'), 
         ('T16','01-08','X1','05','7','S') 



--Function Creation 
Create FUNCTION [dbo].[fn_HIC_6] 
( 
@ProcessID VARCHAR(50) 
) 
RETURNS TABLE 
AS 
RETURN 
(
    -- Add the SELECT statement with parameter references here 
    WITH CTE_Temp AS (
    SELECT 
     ProcessName =  
     CASE 
      WHEN ProcessSheets >= 1 AND ProcessSheets <= 5 THEN '1of' 
      WHEN ProcessSheets >= 6 AND ProcessSheets <= 10 THEN '2of' 
      WHEN ProcessSheets >= 11 AND ProcessSheets <= 16 THEN '3of' 
      WHEN ProcessSheets >= 17 AND ProcessSheets <= 50 THEN '4of' 
      WHEN ProcessSheets > 50 THEN '5of' 
     END 
     , ProcessMABSW 
     ,ProcessID 
     ,[ProcessMEMid]  
    FROM [dbo].[testrun] 
) 
SELECT ProcessName = CASE WHEN GROUPING(ProcessName) = 0 THEN ProcessName ELSE 'Total' END 
     --,Combined_Set = COUNT(DISTINCT(CASE WHEN ProcessMABSW = 'M' THEN [ProcessMEMid] END)) 
    ,Combined_Set  = COUNT(CASE WHEN ProcessMABSW = 'M' THEN ProcessMABSW END) 
    , Non_CombinedSet = COUNT(CASE WHEN ProcessMABSW <> 'M' THEN ProcessMABSW END) 
FROM CTE_Temp 
WHERE [email protected] 
GROUP BY GROUPING SETS (ProcessName,()) 


) 

Однако, для колонки Combined_Set, я не могу правильно рассчитать, что я ищу в изоляции, я могу легко получить правильный результат смотрите ниже код:

--Combined_Set 
WITH CTE_TEMP 
AS 
(

SELECT 
    [ProcessMEMid],Sum(isNULL(Cast([ProcessSheets] as int),0)) Combined 
     ,COUNT([ProcessMEMid]) AS 'Total' 
    FROM [dbo].[testrun] 
    WHERE [ProcessID]='X1' 
    AND [ProcessMABSW]='M' 
    GROUP BY 
     [ProcessMEMid] 


)SELECT  
     CASE 
      WHEN Combined >= 1 AND Combined <= 5 THEN '1of' 
      WHEN Combined >= 6 AND Combined <= 10 THEN '2of' 
      WHEN Combined >= 11 AND Combined <= 16 THEN '3of' 
      WHEN Combined >= 17 AND Combined <= 49 THEN '4of' 
      WHEN Combined > 49 THEN '5of' 
      --WHEN Combined >=1 AND Combined > 49 THEN CAST([Total] as varchar(10)) 
      ELSE CAST([Total] as varchar(10)) 
     END 
     , 
     COUNT([ProcessMEMid]) AS 'Combined' 
FROM CTE_TEMP 
GROUP BY 
CASE 
      WHEN Combined >= 1 AND Combined <= 5 THEN '1of' 
      WHEN Combined >= 6 AND Combined <= 10 THEN '2of' 
      WHEN CombIned >= 11 AND Combined <= 16 THEN '3of' 
      WHEN Combined >= 17 AND Combined <= 49 THEN '4of' 
      WHEN Combined > 49 THEN '5of' 
      --WHEN Combined >=1 AND Combined > 49 THEN CAST([Total] as varchar(10)) 
      ELSE CAST([Total] as varchar(10)) 
      END 

UNION 


    SELECT 
     CASE 
      WHEN 1=1 THEN 'Total' 
      WHEN 2=2 THEN 'Total' 
      WHEN 3=3 THEN 'Tota' 
      WHEN 4=4 THEN 'Total' 
      WHEN 5=5 THEN 'Total' 
      END 
     ,COUNT(distinct [ProcessMEMid]) AS 'Total' 
    FROM [dbo].[testrun] 
    WHERE ProcessID='X1' 
    AND ProcessMABSW='M' 

Вышеприведенные возвращает правильное значение. Мой вопрос в том, как я могу включить Combined_Set запрос в моей функции (эту часть кода Combined_Set = COUNT(CASE WHEN ProcessMABSW = 'M' THEN ProcessMABSW END)

Любой вход будет оценен.

ответ

0

Так что я понял, что вы хотите, чтобы объединить обе части кода в одну функцию. Дайте мне знать, работает ли нижеуказанная функция для вас. Вы можете делать трюки в приведенной ниже функции в соответствии с вашими потребностями:

alter function testfn(@processid as varchar(100)) 
returns table 
as 
return 
(
with cte1 as 
(
select isnull(cast(case 
      when ProcessSheets between 1 and 5 then '1of' 
      when ProcessSheets between 6 and 10 then '2of' 
      when ProcessSheets between 11 and 16 then '3of' 
      when ProcessSheets between 17 and 50 then '4of' 
      when ProcessSheets > 50 then '5of' 
     end as varchar(100)),'Total') as processname, 
     count(case when processmabsw = 'M' then 1 end) as combined_set, 
     count(case when processmabsw <> 'M' then 1 end) as noncombined_set, 
     processid 
from testrun 
group by 
     grouping sets(case 
      when ProcessSheets between 1 and 5 then '1of' 
      when ProcessSheets between 6 and 10 then '2of' 
      when ProcessSheets between 11 and 16 then '3of' 
      when ProcessSheets between 17 and 50 then '4of' 
      when ProcessSheets > 50 then '5of' 
     end,()),processid 
),cte2 as 
(
select processmemid,sum(cast(processsheets as int)) as combined,count(processmemid) as total,processid 
from testrun 
where processmabsw = 'm' 
group by processmemid,processid 
),cte3 as 
(
select isnull(cast(case 
      when combined between 1 and 5 then '1of' 
      when combined between 6 and 10 then '2of' 
      when combined between 11 and 16 then '3of' 
      when combined between 17 and 49 then '4of' 
      when combined > 49 then '5of' 
     end as varchar(10)),'Total') as processname,count(ProcessMEMid) as combined,processid 
from cte2  
group by 
     grouping sets(case 
      when combined between 1 and 5 then '1of' 
      when combined between 6 and 10 then '2of' 
      when combined between 11 and 16 then '3of' 
      when combined between 17 and 49 then '4of' 
      when combined > 49 then '5of' 
     end,()),processid 
) 
select a.processname,a.combined_set,a.noncombined_set,b.combined from cte1 as a 
left join cte3 as b 
on a.processname = b.processname 
where a.processid = @processid 

) 
go 

select * from testfn('x1') 
0

Вы можете попробовать это: -

SELECT ProcessName = CASE WHEN GROUPING(ProcessName) = 0 THEN ProcessName ELSE 'Total' END 
     ,Combined_Set  = CASE WHEN ProcessMABSW = 'M' THEN COUNT(ProcessMABSW) ELSE 0 END 
     , Non_CombinedSet = CASE WHEN ProcessMABSW <> 'M' THEN COUNT(ProcessMABSW) ELSE 0 END 
FROM CTE_Temp 
WHERE [email protected] 
GROUP BY GROUPING SETS (ProcessName,()) 
+0

hanks, но это не сработало. Имейте в виду, что логика Combined_Set и Non_CombinedSet совсем другая. Первые группы, суммы затем рассчитываются на основании условия (см. Код, который объясняет это выше), в то время как последние группы и рассчитывают на определенное условие. - –

+0

любые мысли от кого-нибудь? –

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