SQL Server并使用日期,年份和上一年

时间:2014-02-15 09:44:16

标签: sql sql-server datetime sales

我对SQL Server很陌生,但我仍然设法做了我需要的大部分事情。但是,有一件事我无法理解,并且它与日期一起工作。我有一个这样的数据库用于记录销售:

**Sales**  
    [index] int
    timestamp datetime
    username varchar(10)
    type int
    amount int
    value int
    location int
    receipt text

**Demo**
    index   timestamp   username    type    amount  value   location    receipt
    1   2013-08-14 11:29:29.367 andrer  1   1   10  2   *long text*

我要查询我正在尝试...第一个是过去7天的表格,向我显示每天的客户数量。我的主要问题是能够正确地输出输出,同时仍然以15.02.2014的格式显示输出。这就是我最终的结果。虽然它的工作原理应该......是否有更简单的方法来编写它?

SELECT CONVERT(varchar, DATEADD(dd, 0, DATEDIFF(dd, 0, [timestamp])), 104) as [timestamp], 
       COUNT([username]) as a 
FROM [sales] 
WHERE [timestamp] >= DATEADD(day,-7, GETDATE()) 
GROUP BY DATEADD(dd, 0, DATEDIFF(dd, 0, [timestamp])) 
ORDER BY [timestamp]

我的另一个问题是关于制作一个包含月份名称和当前和去年客户数量的表格。这是过去几周我一直在努力的事情,无法解决如何解决问题。

使用与上面相同的表格,我正在尝试获取和输出这样的内容,其中第一列是月份的名称,第二列是当前年份的客户数量,后面是一列去年的客户数量。

January | 1345 | 299 |
February | 231 | 342 |

...

可悲的是,我今年/上一年的查询还没有正常工作的代码,希望你们中的某个人能够轻松地编写它。 :)

4 个答案:

答案 0 :(得分:1)

SELECT DATENAME(MONTH,[timestamp]) [Month]
      ,COUNT(DISTINCT CASE WHEN YEAR([timestamp]) = YEAR(GETDATE())   
                             THEN username ELSE NULL END) CurrentYear
      ,COUNT(DISTINCT CASE WHEN YEAR([timestamp]) = YEAR(GETDATE())-1 
                             THEN username ELSE NULL END) LastYear
FROM Sales
GROUP BY DATENAME(MONTH,[timestamp]), MONTH([timestamp])
ORDER BY MONTH([timestamp])

这将以

的格式返回数据
╔═══════════╦═════════════╦══════════╗
║   Month   ║ CurrentYear ║ LastYear ║
╠═══════════╬═════════════╬══════════╣
║ February  ║        1000 ║ 0        ║
║ March     ║        1235 ║ 202      ║
║ September ║        1750 ║ 787      ║
╚═══════════╩═════════════╩══════════╝

答案 1 :(得分:0)

关于你的第一个问题:

SELECT CONVERT(varchar, DATEADD(dd, 0, DATEDIFF(dd, 0, [timestamp])), 104) as [timestamp], 
       COUNT([username]) as a 
FROM [sales] 
WHERE [timestamp] >= DATEADD(day,-7, GETDATE()) 
GROUP BY DATEADD(dd, 0, DATEDIFF(dd, 0, [timestamp])) 
ORDER BY  DATEADD(dd, 0, DATEDIFF(dd, 0, [timestamp]))

对于您的第二个请求,您可以尝试:

SELECT datename(month,[timestamp]) as [monthname], COUNT([username]) as Customers, YEAR([timestamp])  as orderyear              
FROM [sales]
GROUP BY  datename(month,[timestamp]), YEAR([timestamp]) 

答案 2 :(得分:0)

对于第二个问题,您可以使用Pivot,如下所示:

select * from
(select distinct datepart(MONTH,datetimestamp) [month], datepart(year,datetimestamp)        [year],
count(username) 
over (partition by datepart(month,datetimestamp), datepart(year, datetimestamp)) [number] 
from Sales) as abc
pivot
(
sum(number)
for [year] in ([2013],[2014])
) as pivottable;

答案 3 :(得分:0)

ORDER BY放在与基础字段同名的别名上有点令人困惑,但我认为您的查询几乎无法改进。

(我可能会放ORDER BY DATEADD(dd, 0, DATEDIFF(dd, 0, [timestamp]))

至于概述,您可以使用PIVOT表。

一些示例代码:

-- create a test-table
IF OBJECT_ID('test') IS NOT NULL DROP TABLE [test] 
GO
CREATE TABLE [test] ( [timestamp] datetime, username int)
GO
-- create some test-data
INSERT [test] ([timestamp], [username])
SELECT TOP 100000
       timestamp = DateAdd(second, - (ABS(BINARY_CHECKSUM(NewID())) % (60 * 60 * 24 * 365 *5)), CURRENT_TIMESTAMP),
       username = ABS(BINARY_CHECKSUM(NewID())) % 10000
  FROM sys.objects o1, sys.objects o2, sys.objects o3

GO

-- original query
SELECT CONVERT(varchar, DATEADD(dd, 0, DATEDIFF(dd, 0, [timestamp])), 104) as [timestamp], 
       COUNT([username]) as a 
 FROM [test] 
WHERE [timestamp] >= DATEADD(day,-7, GETDATE()) 
GROUP BY DATEADD(dd, 0, DATEDIFF(dd, 0, [timestamp])) 
ORDER BY DATEADD(dd, 0, DATEDIFF(dd, 0, [timestamp])) 

-- see how this groups into months
SELECT year = Year([timestamp]),
       month = Month([timestamp]),
       cnt = COUNT([username])
  FROM [test]
 GROUP BY Year([timestamp]), Month([timestamp])


-- use supra in Common Table Expression and use PIVOT to get required result
;WITH mysales (year, month, cnt)
   AS ( SELECT year = Year([timestamp]),
               month = Month([timestamp]),
               cnt = COUNT([username])
          FROM [test]
         GROUP BY Year([timestamp]), Month([timestamp]))

select * from mysales
pivot (SUM (cnt) for year in ([2014],[2013],[2012])) as year

PS:需要注意的一点是,您可能想知道表中出现的不同客户的数量(每个GROUP BY)。为此,您应该使用COUNT(DISTINCT [username])

例如,如果你跑     SELECT COUNT(*), COUNT(object_id), COUNT(collation_name), COUNT(DISTINCT collation_name) FROM sys.columns

  • 第一列将返回找到的记录总数。
  • 第二列将返回找到的object_id的总数;但由于此字段不为NULL,因此它也会返回记录总数。
  • 第三列将返回找到的collat​​ion_names的总数;但由于此字段为NULLable,因此会跳过那些具有该字段NULL值的记录,因此该数字会低很多。
  • 第四列将返回找到的不同collat​​ion_names的数量,不包括NULL。 (这与您对SELECT DISTINCT collation_name FROM sys.columns
  • 的期望略有不同