仅按月和年选择数据

Posted

技术标签:

【中文标题】仅按月和年选择数据【英文标题】:select data only by month and year 【发布时间】:2018-03-23 16:52:45 【问题描述】:

我有一张带有月份和年份的表格:maintable

我想要的是范围选择: result

我认为 between 会是我的朋友,我尝试了以下方法:

SELECT        jahr, monat, alles
FROM            dbo.table
WHERE        (jahr BETWEEN 2017 AND 2018) AND (monat BETWEEN 11 AND 2)

但这不起作用。 我怎样才能得到我想要的?

【问题讨论】:

BETWEEN 边界必须在左侧具有较低的数字,在右侧具有较高的数字。如所写,您的第二个 BETWEEN 子句永远不会评估为真。您可以使用NOT BETWEEN,也可以使用IN 子句 我知道重构数据结构通常不可行,但有一个特定的数据类型:date。它会更适合这项任务。它将简化查询并(作为奖励)节省一点空间。 有了这个解决方案,我还得到了 2017 1 和 2017 2 的组合 Convert month and year combination to date in SQL的可能重复 【参考方案1】:

假设 jahr 和 monat 是整数格式,您可以用它们制作一个键,并可以通过这种方式进行比较。您基本上以 YYYYMM 格式结束。

SELECT        jahr, monat, alles
FROM            dbo.table
WHERE (jahr*100) + monat between 201711 and 201802

【讨论】:

这是一个不错的解决方案,但我对加号有疑问。动态sql中的加号怎么办? @frank 如果加号在你的单引号内,那应该不是问题。只要确保它被视为文本的一部分,就像你的其他保留字(select、from 等......) 我是这样写的,字符串中的所有内容: 我是这样写的,字符串中的所有内容:SET query = 'select * from table WHERE (jahr*100) + monat between ' + von + ' 和 ' + bis + '。错误是:错误转换 nvarchar 'select * from table WHERE (jahr*100) + monat between ' int 数据类型,请想象变量前面的at-sign @frank 好的,我看到了你的问题。您需要将 von 和 bis 转换为 varchar 以便像字符串一样连接它们【参考方案2】:

您可以在不同的条件下简单地比较两个日期。

比较日期是否高于 2017 年 11 月(mont

jahr >= 2017 AND monat >= 11 AND mont <=12

你可以在 jahr >= 2017 AND monat 介于 11 和 12 之间

比较日期是否低于 2018 年 2 月(mont >= 1 用作安全检查,如果您可以保证月份列不包含小于 1 的值,则可以忽略它)。

jahr <= 2018 AND monat >= 1 AND mont <=2

你可以在之间使用

jahr >= 2017 AND monat between 1 AND 2

使用简单运算符的整体条件

(jahr >= 2017 AND monat >= 11 AND monat <=12) AND (jahr <= 2018 AND monat >= 1 AND monat <=2)

在条件之间

(jahr >= 2017 AND monat between 11 AND 12) AND (jahr >= 2017 AND monat between 1 AND 2)

以下是您的问题的确切 sql。所有三个查询都应该适合您的目的。

-- With simple operators
SELECT        jahr, monat, alles
FROM          dbo.table
WHERE         (jahr >= 2017 AND monat >= 11 AND monat <=12) 
AND (jahr <= 2018 AND monat >= 1 AND monat <=2)

-- With simple operators (Without security boundary checks)
SELECT        jahr, monat, alles
FROM          dbo.table
WHERE         (jahr >= 2017 AND monat >= 11) 
AND (jahr <= 2018 AND monat <=2)

-- With between operator
SELECT        jahr, monat, alles
FROM          dbo.table
WHERE         (jahr >= 2017 AND monat between 11 AND 12)
AND (jahr >= 2017 AND monat between 1 AND 2)

【讨论】:

【参考方案3】:

我会这样做

SELECT  jahr, monat, alles 
FROM table1
WHERE cast(cast(jahr as varchar(20))+'-'+cast(monat as varchar(20))+'-01' as date) >=  '2017-11-01'
 and cast(cast(jahr as varchar(20))+'-'+cast(monat as varchar(20))+'-01' as date) <='2018-02-01'

我认为这是最好的解决方案,因为您让服务器处理细节——您正在获取数据模型并转换为日期类型,然后让服务器对过滤器进行日期比较。

http://sqlfiddle.com/#!18/13a69/21/0

调试

http://sqlfiddle.com/#!18/13a69/20/0

【讨论】:

用加号代替管道也试过了,得到的错误消息是不允许从 int 显式转换为 date 看起来管道 (||) 仅是 oracle @keithl -- pipe pipe 是连接字符串的 sql 标准。 @frank 我在上面进行了更改,以便在连接之前将整数转换为字符串。 @frank -- 我使用了 jay 的 sql fiddle 来获得完全正确的语法【参考方案4】:
SELECT        jahr, monat, alles
FROM           dbo.table
WHERE (jahr = 2017 AND monat IN (11,12))
      OR (jahr = 2018 AND monat IN (1,2))

输出

jahr    monat   alles
2017    11      105
2017    12      105
2018    1       104
2018    2       105

演示链接

http://sqlfiddle.com/#!18/13a69/1

【讨论】:

【参考方案5】:
SELECT        jahr, monat, alles
FROM            dbo.table
WHERE        ( jahr = 2017 AND monat BETWEEN 11 AND 12 )
             OR 
             ( jahr = 2018 AND monat BETWEEN 1 AND 2 )

【讨论】:

【参考方案6】:

您可以尝试以下查询。

SELECT        jahr, monat, alles
FROM           table1
WHERE CASE WHEN (jahr = 2017 AND monat BETWEEN 11 AND 12) THEN 1
            WHEN (jahr = 2018 AND monat BETWEEN 1 AND 2) THEN 1 
            ELSE 0 END = 1

谢谢

【讨论】:

【参考方案7】:

您可以使用 OR 运算符和一些括号:

DECLARE @maintable TABLE (jahr int, monat int, alles int)
INSERT INTO @maintable VALUES
(2017, 7, 189),(2017, 8, 125),(2017, 9, 92),(2017, 10, 98),(2017, 11, 105)
,(2017, 12, 105),(2018, 1, 104),(2018, 2, 105),(2018, 3, 99)

SELECT jahr
      ,monat      
      ,alles 
  FROM @maintable
WHERE (jahr >= 2017 AND monat >= 11)
      OR
      (jahr <= 2018 AND monat <= 2)

生产:

jahr    monat   alles
2017    11      105
2017    12      105
2018    1       104
2018    2       105

【讨论】:

以上是关于仅按月和年选择数据的主要内容,如果未能解决你的问题,请参考以下文章

什么策略建议按月和年分配数据帧以获得R中的单个数据帧列表

在 postgresql 中按月和年对查询结果进行分组

Django按月和年过滤

LINQ:在日期时间字段中按月和年分组

如何在 Jooq 中按月和年将毫秒翻译成日期和分组?

pandas:按月和天匹配数据