按日期查询数据库的SQL代码

时间:2014-04-22 12:07:55

标签: sql sql-server-2005

我有点像SQL新手,但我们的任务是提出一些代码来从历史数据库中检索值。我在一年中的每个月的特定时间检索对象(标记)的名称及其值。但是,年份将是来自报告的用户定义参数。因此,如果用户选择2014,则应在2014年1月1日/ 2014年1月1日查询,依此类推。

我想出了查询的简单部分,它正在查找标签名称和相关值:

SELECT Tagname,value  
   From runtime.dbo.History
   WHERE Tagname IN ('Tag1', 'Tag2')
   and wwVersion = 'Latest'
   and DateTime = @Date

以下是我需要解决的问题: 1.我可以手动设置@Date,但我想让它做到如上所述。我认为可能会使用某种类型的循环? 2.我不确定如何将其输出为表格格式,如下所示:

Tag 1, (jan value), (feb value), (mar value), etc...
Tag 2, (jan value), (feb value), (mar value), etc...

任何帮助将不胜感激。谢谢!

2 个答案:

答案 0 :(得分:0)

  1. 您想要查询一段时间内的数据,因此DateTime应该在一个范围内。例如。 DateTime> @DateStart和DateTime< @DateEnd
  2. 如果要先使用Tag1查询数据,然后使用Tag2查询数据,请尝试使用group by子句。如果您需要添加一些表头,您可以循环查询数据,每次查询具有相同标记的数据。

答案 1 :(得分:0)

如果每个标签每月只有一个值,则可以使用条件聚合来选择记录。我已经去了MAX函数,但是如果你只有一个值它是任意的:

DECLARE @Year INT;
SET @Year = 2013;

-- CONVERT TO A DATE TO ALLOW A SARGEABLE PREDICATE IN THE WHERE CLAUSE
DECLARE @Date SMALLDATETIME;
SET @Date = CONVERT(SMALLDATETIME, CONVERT(CHAR(4), @Year) + '0101', 112);

SELECT  Tagname,
        Jan = MAX(CASE WHEN DATEPART(MONTH, DateTime) = 1 THEN value END),
        Feb = MAX(CASE WHEN DATEPART(MONTH, DateTime) = 2 THEN value END),
        Mar = MAX(CASE WHEN DATEPART(MONTH, DateTime) = 3 THEN value END),
        Apr = MAX(CASE WHEN DATEPART(MONTH, DateTime) = 4 THEN value END),
        May = MAX(CASE WHEN DATEPART(MONTH, DateTime) = 5 THEN value END),
        Jun = MAX(CASE WHEN DATEPART(MONTH, DateTime) = 6 THEN value END),
        Jul = MAX(CASE WHEN DATEPART(MONTH, DateTime) = 7 THEN value END),
        Aug = MAX(CASE WHEN DATEPART(MONTH, DateTime) = 8 THEN value END),
        Sep = MAX(CASE WHEN DATEPART(MONTH, DateTime) = 9 THEN value END),
        Oct = MAX(CASE WHEN DATEPART(MONTH, DateTime) = 10 THEN value END),
        Nov = MAX(CASE WHEN DATEPART(MONTH, DateTime) = 11 THEN value END),
        Dec = MAX(CASE WHEN DATEPART(MONTH, DateTime) = 12 THEN value END)
FROM    runtime.dbo.History
WHERE   Tagname IN ('Tag1', 'Tag2')
AND     wwVersion = 'Latest'
AND     DateTime >= @Date
AND     DateTime < DATEADD(YEAR, 1, @Date)
GROUP BY TagName;

如果您有多个值,那么您需要应用某种逻辑来选择正确的值。在下面的例子中,我已经找到了每个月的第一个值:

DECLARE @Year INT;
SET @Year = 2013;

-- CONVERT TO A DATE TO ALLOW A SARGEABLE PREDICATE IN THE WHERE CLAUSE
DECLARE @Date SMALLDATETIME;
SET @Date = CONVERT(SMALLDATETIME, CONVERT(CHAR(4), @Year) + '0101', 112);

SELECT  Tagname,
        Jan = MAX(CASE WHEN DATEPART(MONTH, DateTime) = 1 THEN value END),
        Feb = MAX(CASE WHEN DATEPART(MONTH, DateTime) = 2 THEN value END),
        Mar = MAX(CASE WHEN DATEPART(MONTH, DateTime) = 3 THEN value END),
        Apr = MAX(CASE WHEN DATEPART(MONTH, DateTime) = 4 THEN value END),
        May = MAX(CASE WHEN DATEPART(MONTH, DateTime) = 5 THEN value END),
        Jun = MAX(CASE WHEN DATEPART(MONTH, DateTime) = 6 THEN value END),
        Jul = MAX(CASE WHEN DATEPART(MONTH, DateTime) = 7 THEN value END),
        Aug = MAX(CASE WHEN DATEPART(MONTH, DateTime) = 8 THEN value END),
        Sep = MAX(CASE WHEN DATEPART(MONTH, DateTime) = 9 THEN value END),
        Oct = MAX(CASE WHEN DATEPART(MONTH, DateTime) = 10 THEN value END),
        Nov = MAX(CASE WHEN DATEPART(MONTH, DateTime) = 11 THEN value END),
        Dec = MAX(CASE WHEN DATEPART(MONTH, DateTime) = 12 THEN value END)
FROM    (   SELECT  TagName, 
                    DateTime,
                    Value,
                    RowNum = ROW_NUMBER() OVER(PARTITION BY TagName, DATEPART(MONTH, DateTime), DATEPART(YEAR, DateTime)
                                                ORDER BY DateTime)
            FROM    runtime.dbo.History
            WHERE   Tagname IN ('Tag1', 'Tag2')
            AND     wwVersion = 'Latest'
            AND     DateTime >= @Date
            AND     DateTime < DATEADD(YEAR, 1, @Date)
        ) h
WHERE   h.RowNum = 1
GROUP BY TagName;