按日期获取计数列表

时间:2016-01-21 12:53:28

标签: sql sql-server

我有两张桌子。一个包含应用程序列表。另一个包含每周与他们相关的计数。现在我想得到应用程序名称和本周以及之前的计数。让我解释一下。

应用程式:

+----+-------------+
| id | name        |
+----+-------------+
| 1  | Office 2007 |
+----+-------------+
| 2  | Office 2010 |
+----+-------------+
| 3  | Office 2013 |
+----+-------------+

数:

+----+--------+-------+------------+
| id | app_id | count | date       |
+----+--------+-------+------------+
| 1  | 1      | 200   | 2016-01-11 |
+----+--------+-------+------------+
| 2  | 2      | 500   | 2016-01-11 |
+----+--------+-------+------------+
| 3  | 3      | 750   | 2016-01-11 |
+----+--------+-------+------------+
| 4  | 1      | 180   | 2016-01-18 |
+----+--------+-------+------------+
| 5  | 2      | 378   | 2016-01-18 |
+----+--------+-------+------------+
| 6  | 3      | 1000  | 2016-01-18 |
+----+--------+-------+------------+

这是我需要的结果。我需要所有应用程序,包括本周和之前的计数:

+-------------+-----------------+-----------------+
| app         | count_this_week | count_prev_week |
+-------------+-----------------+-----------------+
| Office 2007 | 180             | 200             |
+-------------+-----------------+-----------------+
| Office 2010 | 378             | 500             |
+-------------+-----------------+-----------------+
| Office 2013 | 1000            | 750             |
+-------------+-----------------+-----------------+

每周运行一个填充count表的脚本。现在我需要每周收到一份报告。 老实说我有点迷失,因为我不知道如何宣布列的条件。

3 个答案:

答案 0 :(得分:2)

您可以尝试先按DATEPART(WEEK,C.date),name分组,然后使用另一个GROUP BY将计数分成2列。像这样的东西

修改

如果每个应用每周只有1条记录,则只能使用一个group by这样的记录。

SELECT
    appname,
    SUM(CASE WHEN weekno = 0 THEN sumcount ELSE 0 END) as thisweek,
    SUM(CASE WHEN weekno = 1 THEN sumcount ELSE 0 END) as lastweek
FROM
(
    SELECT 
        DATEPART(WEEK,CURRENT_TIMESTAMP) - DATEPART(WEEK,C.date) as weekno,
        name as appname,
        count as sumcount
    FROM App A 
    INNER JOIN CountTable C ON A.[id] = C.[app_id]
    WHERE DATEPART(WEEK,C.date) BETWEEN DATEPART(WEEK,CURRENT_TIMESTAMP) - 1  AND DATEPART(WEEK,CURRENT_TIMESTAMP) 
)T
GROUP BY appname

<强>查询

SELECT 
    appname,
    SUM(CASE WHEN weekno = 0 THEN sumcount ELSE 0 END) as thisweek,
    SUM(CASE WHEN weekno = 1 THEN sumcount ELSE 0 END) as lastweek
FROM
(
    SELECT
        DATEPART(WEEK,CURRENT_TIMESTAMP) - DATEPART(WEEK,C.date) as weekno,
        name as appname,
        SUM(count) as sumcount
    FROM App A INNER JOIN CountTable C ON A.[id] = C.[app_id]
    WHERE DATEPART(WEEK,C.date) BETWEEN DATEPART(WEEK,CURRENT_TIMESTAMP) - 1  AND DATEPART(WEEK,CURRENT_TIMESTAMP) 
    GROUP BY DATEPART(WEEK,C.date),name
) AS T
GROUP BY appname

<强> SQL Fiddle

<强>输出

|     appname | thisweek | lastweek |
|-------------|----------|----------|
| Office 2007 |      180 |      200 |
| Office 2010 |      378 |      500 |
| Office 2013 |     1000 |      750 |

答案 1 :(得分:0)

您可以将此通用查询与当前工作日的变量一起使用:

DECLARE @week date = '2016-01-18';

WITH data AS (
    SELECT a.name, c.[count] 
        , w = CASE WHEN c.[date] = @week THEN 0 ELSE 1 END
    FROM @Counts c
    INNER JOIN @Apps a ON c.app_id = a.id
    WHERE [date] = @week OR [date] = DATEADD(day, -7, @week)
)
SELECT App = name, count_this_week = [0], count_prev_week = [1]
FROM data d
PIVOT (
    MAX([count])
    FOR w IN ([0], [1])
) p

<强>输出:

App         count_this_week count_prev_week
Office 2007 180             200
Office 2010 378             500
Office 2013 1000            750

您的数据:

DECLARE @Apps TABLE ([id] int, [name] varchar(11));
DECLARE @Counts TABLE([id] int, [app_id] int, [count] int, [date] date);

INSERT INTO @Apps([id], [name])
VALUES
    (1, 'Office 2007'),
    (2, 'Office 2010'),
    (3, 'Office 2013')
;

INSERT INTO @Counts([id], [app_id], [count], [date])
VALUES
    (1, 1, 200, '2016-01-11'),
    (2, 2, 500, '2016-01-11'),
    (3, 3, 750, '2016-01-11'),
    (4, 1, 180, '2016-01-18'),
    (5, 2, 378, '2016-01-18'),
    (6, 3, 1000, '2016-01-18')
;

答案 2 :(得分:-2)

SELECT * 
FROM count 
JOIN app ON app.id=count.app_id
WHERE date BETWEEN '2016-01-18' AND '2016-01-11'