2014-10-09 43 views
0

抱歉模糊的标题!合并具有相同核心语法的多个查询

我建立一个Web过滤器,用户就可以点击选择和使用MS-SQL 2012

我已经是我跑4个查询上进行打造每一个选择的问题过滤下来的结果过滤器和1结果。

忽略它如何被最好的编码,所以我不必重新加载过滤查询每一次,我需要帮助,我怎么能合并产生的过滤选项和计数为1

4个查询语法的核心与大多数逻辑基于过滤后的选择提取结果的情况相同。但是,我仍然需要生成过滤器和他们的计数。

 select datePart(yy,p.startDate) year, count(p.personId) itemCount 
     from person p 
     where p.field1 = something 
     and p.field2 = somethingElse... 

是否有运行的核心和生产过滤器列表和计数(见下文)于一身,而不是单独做各自的方式吗?

以下是2个过滤器的示例,但也有其他人做类似的事情,可以根据现有数据生成列表或根据特定日期之前,之间和之后生成列表。

--Filter 1 to get years and counts 
with annualList as 
(
    select a.year 
    from table a 
    where a.year > 2000 
) 
select al.year, isnull(count,0) itemCount 
from annualList al 
left join (
     select datePart(yy,p.startDate) year, count(p.personId) itemCount 
     from person p 
     where p.field1 = something 
     and p.field2 = somethingElse... 
    ) group by datePart(yy,p.startDate) persons 
on al.year = persons.year 
order by al.year desc; 

--filter 2 to get group stats 
select anotherList.groupStatus, groupStatusCounts.itemCount 
from (
    select 'Child' as groupStatus 
    union all 
    select 'Adult' as groupStatus 
    union all 
    select 'Pensioner' as groupStatus 
) anotherList 
left join (
    SELECT personStatus.groupStatus, count(personStatus.personId) itemCount 
    FROM (select p.personId 
      case when (p.age between 1 and 17) then 'Child' 
      case when (p.age between 18 and 67) then 'Adult' 
      case when (p.age > 65) then 'Pensioner' 
      end as groupStatus 
      FROM person p 
      --and some other syntax to calculate the age... 
      where p.field1 = something 
      and p.field2 = somethingElse exactly as above query... 
     ) personStatus 
     GROUP BY personStatus.groupStatus 
    ) groupStatusCounts 
ON anotherList.groupStatus = groupStatusCounts.groupStatus 

作为一个示例,使用下面的数据集,从regDate和使用一组由I将能够从2010 - 2014年获得(过滤器1上面的代码)的年列表。

使用dataofbirth我需要'计算'groupStatus使用案例。正如你从数据分娩数据中可以看到的,我没有任何记录可以找到养老金领取者,因此我写过滤器2的方式(见上面的代码),即使我没有,它也会给我我需要的过滤器数据来表示它。

尝试添加对SQL小提琴代码可惜是向下昨晚

INSERT INTO personTable 
    ([PersonID], [dateOfBirth], [regDate]) 
VALUES 
    (1, '1979-01-01 00:00:00', '2010-01-01 00:00:00'), 
    (2, '1979-01-01 00:00:00', '2010-01-01 00:00:00'), 
    (3, '1979-01-01 00:00:00', '2011-01-01 00:00:00'), 
    (4, '1979-01-01 00:00:00', '2011-01-01 00:00:00'), 
    (5, '1979-01-01 00:00:00', '2012-01-01 00:00:00'), 
    (6, '1979-01-01 00:00:00', '2012-01-01 00:00:00'), 
    (7, '1984-01-01 00:00:00', '2012-01-01 00:00:00'), 
    (8, '1992-01-01 00:00:00', '2012-01-01 00:00:00'), 
    (9, '2000-01-01 00:00:00', '2013-01-01 00:00:00'), 
    (10, '2010-01-01 00:00:00', '2014-01-01 00:00:00') 

my example of SQL Fiddle

结果要结束了,我需要它看起来像此基础上所示的结果小提琴

filter  | Year | groupStatus 
-----------+-----------+-------- 
2010  | 0  | null 
2011  | 2  | null 
2012  | 3  | null 
2013  | 0  | null 
2014  | 3  | null 
child  | null | 2 
adult  | null | 6 
pensioner | null | 0 

请多关照

回答

0

我可能大量误解了这个要求,但是我怀疑你想使用GROUPING SETS。举一个简单的例子(忽略你的具体的过滤器)想象一下下面这个简单的数据集:

PersonID | GroupStatus | Year 
---------+-------------+-------- 
    1 | Adult  | 2013 
    2 | Adult  | 2013 
    3 | Adult  | 2014 
    4 | Adult  | 2014 
    5 | Adult  | 2014 
    6 | Child  | 2012 
    7 | Child  | 2014 
    8 | Pensioner | 2012 
    9 | Pensioner | 2013 
    10 | Pensioner | 2013 

从我所收集你试图让2所不同的总结出这个数据的不重复的查询,例如

GroupStatus | ItemCount 
------------+----------- 
    Adult |  5 
    Child |  2 
    Pensioner |  3 

而且

Year | ItemCount 
------------+----------- 
    2012 |  2 
    2013 |  4 
    2014 |  4 

您可以在一个单一的数据获得的这个集合使用:

SELECT Year, 
     GroupStatus, 
     ItemCount = COUNT(*) 
FROM T 
GROUP BY GROUPING SETS ((Year), (GroupStatus)); 

这将产生一个数据集:

YEAR GROUPSTATUS  ITEMCOUNT 
------------------------------------ 
NULL Adult   5 
NULL Child   2 
NULL Pensioner  3 
2012 NULL   2 
2013 NULL   4 
2014 NULL   4 

如果您还想包括完整的数据,你可以进去包括具有所有字段的分组,例如(PersonID, Year, GroupStatus)

Examples on SQL Fiddle

编辑

下面的查询为您提供所要求的输出:

WITH AllValues AS 
( SELECT TOP (DATEPART(YEAR, GETDATE()) - 2009) 
      Filter = CAST(2009 + ROW_NUMBER() OVER(ORDER BY object_id) AS VARCHAR(15)), 
      FilterType = 'Year' 
    FROM sys.all_objects o 
    UNION ALL 
    SELECT Filter, 'GroupStatus' 
    FROM (VALUES ('child'), ('Adult'), ('Pensioner')) T (Filter) 
) 
SELECT v.Filter, 
     [Year] = CASE WHEN v.FilterType = 'Year' THEN ISNULL(data.ItemCount, 0) END, 
     GroupStatus = CASE WHEN v.FilterType = 'GroupStatus' THEN ISNULL(data.ItemCount, 0) END 
FROM AllValues AS v 
     LEFT JOIN 
     ( SELECT [Year] = DATENAME(YEAR, t.RegDate), 
        Age = a.Name, 
        ItemCount = COUNT(*) 
      FROM T 
        LEFT JOIN 
        (VALUES 
         (0, 18, 'Child'), 
         (18, 65, 'adult'), 
         (65, 1000000, 'pensioner') 
        ) a (LowerValue, UpperValue, Name) 
         ON a.LowerValue <= DATEDIFF(HOUR, T.dateofbirth, GETDATE())/8766.0 
         AND a.UpperValue > DATEDIFF(HOUR, T.dateofbirth, GETDATE())/8766.0 
      WHERE T.PersonID > 2 
      GROUP BY GROUPING SETS ((DATENAME(YEAR, t.RegDate)), (a.Name)) 
     ) AS data 
      ON ISNULL(data.[Year], data.Age) = v.Filter; 

Example on SQL Fiddle

+0

的问题是一些“过滤器'(即groupStatus)需要'计算',并且不在系统中供我首先进行分组。同样在你的例子中,“过滤器”返回将仅基于表中的内容。但是,如果您有2010-2013年的数据,但2014年没有数据,则过滤器将不会显示2010,2011,2012,2013 2014年剩下的数据,并且也需要显示。 – 2014-10-09 13:02:20

+0

您是否可以将一些示例数据和预期输出发布到您的问题中,因为我认为我误解了您的问题。 – GarethD 2014-10-09 13:19:57