如何使用Group这样显示SQL查询?

时间:2014-05-11 19:21:26

标签: sql sql-server sql-server-2005

2i ll仅列出了我需要查询的1个表:

lodgings_Contract:

id_contract     indentity primary,    
id_person       int,   
id_room         varchar(4),   
day_begin       datetime,   
day_end         datetime,
day_register    datetime  
money_per_month money

这是table lodgings_Contract的值(此数据仅用于示例):

id_contract | id_person | id_room | day_begin -----|  day_end ----- | day_register------- | money_per_month

          3 |      2 |   101 | 1/12/2014  | 27/2/2015 |   1/12/2015   |       100
          2 |      1 |   102 | 1/1/2014   | 27/4/2014 |   1/1/2014    |       200
          1 |      3 |   103 | 1/1/2014   | 27/3/2014 |   1/1/2014    |       300
*人1租房102房间2014年4个月200 /月和人2租房101房3个月但1个月2014年和2个月2015年100 /月。人3租房103 2014年3个月,每月300件

我想要我的结果显示3字段:月|年|收入

结果:

月|年|收入

1  |2014|  500
2  |2014|  500
3  |2014|  500
4  |2014|  200
12 |2014|  100
1  |2015|  100
2  |2015|  100

我能这样做吗?请帮帮我!

我在这篇文章之前发布了另一篇文章,但它很复杂,需要3个表格,所以我只用一张桌子发帖。

这是我的代码:

select month(day_begin)as 'Month',year(day_begin)as 'Year',money_per_month as 'Incomes'
from lodgings_Contract
group by day_begi,money_per_month

它只列出了第一个月的“day_begin”。我不知道该怎么做

1 个答案:

答案 0 :(得分:0)

要获得结果,您首先需要一个日历表,以下查询是使用CTE动态创建的 那说明day_register列的目的是什么?它似乎是day_begin的副本,可能是ID 3合同的拼写错误。

WITH Months(N) AS (
  SELECT 1 UNION ALL Select 2 UNION ALL Select 3 UNION ALL Select 4
  UNION ALL Select 5 UNION ALL Select 6 UNION ALL Select 7 UNION ALL Select 8
  UNION ALL Select 9 UNION ALL Select 10 UNION ALL Select 11 UNION ALL Select 12
), Calendar(N) As (
  SELECT CAST(2010 + y.N AS VARCHAR) + RIGHT('00' + Cast(m.N AS VARCHAR), 2)
  FROM   Months m
         CROSS JOIN Months y
)
SELECT RIGHT(c.N, 2) [Month]
     , LEFT(c.N, 4) [Year]
     , SUM(money_per_month) Incomes
FROM   lodgings_Contract lc
       INNER JOIN Calendar c 
                  ON c.N BETWEEN CONVERT(VARCHAR(6), lc.day_begin, 112)
                             AND CONVERT(VARCHAR(6), lc.day_end, 112)
GROUP BY c.N

日历CTE很小,因为我不知道真实数据有多少年。如果有多年,最好在数据库中创建一个日历表并使用它而不是每次都计算它 日历CTEyyyyMM格式返回月份列表 在主查询中,CONVERT(VARCHAR(6),lc.day_begin,112)将day_begin更改为ISO格式yyyyMMdd并仅取前六个值,因此再次yyyyMM,例如,对于id_contract 3,我们将201412,对于day_end也是如此 如果合同的开头是day_register,则将lc.day_begin更改为lc.day_register

SQLFiddle演示