SQL查询以选择两个日期之间的日期,并排除两个日期之间的日期

时间:2018-08-21 04:45:44

标签: sql sql-server between

CREATE TABLE [dbo].[#temp1]
(
    [workDate] [datetime] NULL,
    [Id] [int] NULL,
) ON [PRIMARY]

INSERT INTO [dbo].[#temp1] 
VALUES ('12-01-2018', '11'), ('11-01-2018', '11'),
       ('10-01-2018', '11'), ('09-01-2018', '11')


CREATE TABLE [dbo].[#temp2]
(
    [workDate] [datetime] NULL,
    [Id] [int] NULL,
) ON [PRIMARY]

INSERT INTO [dbo].[#temp2] 
VALUES ('10-01-2018', '11'), ('09-01-2018', '11')

我有2张有日期的桌子。

我想选择#temp1中的所有日期,但不计算#temp2中的日期。

我用过,但没有得到想要的结果:

select A.workDate, A.Id
from [dbo].[#temp1] A
left join [dbo].[#temp2] B on A.Id = B.Id and A.workDate = B.workDate
where A.workDate between CAST('09.01.2018' as datetime) and CAST('12.01.2018' as datetime)
   or B.workDate not between CAST('09.01.2018' as datetime) and CAST('10.01.2018' as datetime)

我想要得到的结果:

workDate                   Id
-------------------------------
2018-01-12 00:00:00.000    11
2018-01-11 00:00:00.000    11

如何解决?

4 个答案:

答案 0 :(得分:0)

编写查询的方式取决于表中的值。如果您已经知道要选择的日期,则可以执行以下操作:

where A.workDate between CAST('11.01.2018' as datetime) and CAST('12.01.2018' as datetime)

您可能想要的是选择left join不匹配的行:

where B.workDate is null

答案 1 :(得分:0)

A.Id=B.Id-连接谓词中的此条件在逻辑上是错误的/没有任何意义。您正在谈论比较日期-这里Id的用途是什么?关于ORwhere部分的问题。

您所说的工作:#temp1以外的日期,#temp2以外的日期-可以将其从英语“翻译”成SQL几乎是逐词:

select A.workDate
from [dbo].[#temp1] A
where A.workDate between CAST('09.01.2018' as datetime) and CAST('12.01.2018' as datetime)

EXCEPT

select B.workData
from [dbo].[#temp2] B

”来自#temp1的日期,该日期在#temp2中不存在”

select A.workDate,A.Id
from [dbo].[#temp1] A
where A.workDate between CAST('09.01.2018' as datetime) and CAST('12.01.2018' as datetime)
  AND not exists(select 1 from [dbo].[#temp2] B WHERE B.workDate = A.workDate)

是的,很简单。

此外,您最好不要投放这样的日期:CAST('09.01.2018' as datetime)。 “默认”日期format取决于设置,例如

  • ddmmyy德语
  • yymmdd ANSI
  • mmddyy美国

因此,此转换可能会导致不同的日期(09月01日还是09月01日?) 使用CONVERT(datetime, '09.01.2018', 104)。最好不要在查询中使用文字和魔术字符串/数字-将这些值放入变量中并像这样使用它们:

declare @date_begin date = CONVERT(date, '20180109', 112),
        @date_end date = CONVERT(date, '20180112', 112)

select A.workDate,A.Id
from [dbo].[#temp1] A
where A.workDate between @date_begin and @date_end
  AND not exists(select 1 from [dbo].[#temp2] B WHERE B.workDate = A.workDate)

答案 2 :(得分:0)

如果要选择日期在两个日期值之间并且不在另一个表中的行,请首先在Between .. and子句中使用Where选择行,然后忽略属于其他使用 Not Exists 的表。

查询

select * from [dbo].[#temp1] as [t1]
where cast([workDate] as date) between '2018-09-01' and '2018-12-01'
and not exists(
    select 1 from [dbo].[#temp2] as [t2]
    where [t1].[workDate] = [t2].[workDate]
);

答案 3 :(得分:0)

使用and条件更新查询,如下所示。并检查B.workDate IS NULL中是否存在记录[dbo].[#temp2]中没有记录,然后它将给出结果。

select A.workDate, A.Id
from [dbo].[#temp1] A
left join [dbo].[#temp2] B on A.Id = B.Id and A.workDate = B.workDate
where A.workDate between CAST('09.01.2018' as datetime) and CAST('12.01.2018' as datetime)
and (B.workDate IS NULL or B.workDate not between CAST('09.01.2018' as datetime) and CAST('10.01.2018' as datetime)