Sql 仅按月份和年份选择数据

Sql 仅按月份和年份选择数据,sql,sql-server,Sql,Sql Server,我有一张包含月份和年份的表格: 我想要的是一个范围选择: 我想中间会是我的朋友,我尝试了以下方法: SELECT jahr, monat, alles FROM dbo.table WHERE (jahr BETWEEN 2017 AND 2018) AND (monat BETWEEN 11 AND 2) 但这是行不通的。 我怎样才能得到我想要的 SELECT jahr, monat, alles FROM

我有一张包含月份和年份的表格:

我想要的是一个范围选择:

我想中间会是我的朋友,我尝试了以下方法:

SELECT        jahr, monat, alles
FROM            dbo.table
WHERE        (jahr BETWEEN 2017 AND 2018) AND (monat BETWEEN 11 AND 2)
但这是行不通的。 我怎样才能得到我想要的

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
演示链接

输出

jahr    monat   alles
2017    11      105
2017    12      105
2018    1       104
2018    2       105
演示链接


假设jahr和monat是整数格式,您可以用它们制作一个键,并以这种方式进行比较。实际上,最终的结果是YYYYMM格式

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

假设jahr和monat是整数格式,您可以用它们制作一个键,并以这种方式进行比较。实际上,最终的结果是YYYYMM格式

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

您可以尝试以下查询

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

谢谢

您可以尝试以下查询

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

谢谢

您可以在不同的条件下比较这两个日期,如下所示


比较日期高于2017年11月您可以在不同条件下比较两个日期,如下所示


比较一下,日期在2017年11月的上方我会这样做

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'
我认为这是最好的解决方案,因为您需要让服务器处理细节——您需要将数据模型转换为日期类型,然后让服务器对过滤器进行日期比较

调试


我会这样做

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'
我认为这是最好的解决方案,因为您需要让服务器处理细节——您需要将数据模型转换为日期类型,然后让服务器对过滤器进行日期比较

调试


可以使用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)

可以使用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)


边界之间的数字必须左低右高。如前所述,您的第二个BETWEEN子句将永远不会为true。您可以使用NOT-BETWEEN,也可以使用IN子句来代替head,我知道重构数据结构通常是不可行的,但是这有一种特定的数据类型:date。它更适合这项任务。这将简化查询,并作为奖励,节省一点空间。使用此解决方案,我还得到2017 1和2017 2边界之间可能的重复组合,左侧的数字较低,右侧的数字较高。如前所述,您的第二个BETWEEN子句将永远不会为true。您可以使用NOT-BETWEEN,也可以使用IN子句来代替head,我知道重构数据结构通常是不可行的,但是这有一种特定的数据类型:date。它更适合这项任务。这将简化查询,并作为奖励,节省一些空间。使用此解决方案,我还获得了2017 1和2017 2的组合,这是一个很好的解决方案,但我对加号有问题。如何处理动态sql中的加号?@frank如果您的单引号中的加号不应该是问题。只需确保它与其他保留字select、from等一样被视为文本的一部分……我是这样写的,字符串中的所有内容:我是这样写的,字符串中的所有内容:SET query='select*from table,其中jahr*100+monat介于'+von+'和'+bis+'之间。错误是:在int数据类型中,转换nvarchar“select”时出错,其中jahr*100+monat介于之间,请想象前面的at符号variables@frank好的,我看到你的问题了。您需要将von和bis转换为varchar,以便像strings一样连接它们。这是一个很好的解决方案,但我对加号有一个问题。如何处理动态sql中的加号?@frank如果您的单引号中的加号不应该是问题。只需确保它与其他保留字select、from等一样被视为文本的一部分……我是这样写的,字符串中的所有内容:我是这样写的,字符串中的所有内容:SET query='select*from table,其中jahr*100+monat介于'+von+'和'+bis+'之间。错误是:在int数据类型中,转换nvarchar“select”时出错,其中jahr*100+monat介于之间,请想象前面的at符号variables@frank好的,我看到你的问题了。您需要将von和bis转换为varchar,以便像stringstried一样将它们连接起来,并使用加号而不是管道,获取不允许从int显式转换为date的错误消息看起来像pipe pipe | |是oracleonly@keithl-pipe pipe是concat字符串的sql标准。@frank我在上面对其进行了更改,以便在连接之前将整数转换为字符串。@frank-我使用jay的sql FIDLE完全正确地获取语法,并使用plus进行了尝试签名而不是管道,获取错误消息,即不允许从int显式转换为date看起来管道| |是oracleonly@keithl-pipe pipe是concat字符串的sql标准。@frank我在上面更改了它,以便在连接之前将整数转换为字符串。@frank-我使用jay的sql FIDLE使语法完全正确
jahr    monat   alles
2017    11      105
2017    12      105
2018    1       104
2018    2       105