SQL 查询两个日期之间的 select 个日期并排除两个日期之间的日期
SQL query to select dates between two dates and exclude dates between two dates
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 个带日期的表格。
我想 select #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
如何解决?
您编写查询的方式取决于表中的值。如果您已经知道要 select 的日期,您可以这样做:
where A.workDate between CAST('11.01.2018' as datetime) and CAST('12.01.2018' as datetime)
您可能想要的是 select 行,其中 left join
不匹配任何内容:
where B.workDate is null
A.Id=B.Id
- 连接谓词中的这个条件在逻辑上是 wrong/makes 没有意义。你说的是比较日期 - Id
会在这里做什么? where
中的 OR
部分也是如此。
正如你所说的你的工作:从#temp1 开始的日期除了从#temp2 开始的日期 - 它可以是 "translated" 从英语到 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
或"dates from #temp1 which do not exist in #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)
。 "Default" 日期 format 取决于设置,例如可以是
ddmmyy
德语
yymmdd
ANSI
mmddyy
美国
因此此转换可能会产生不同的日期(09 月 01 日或 01 月 09 日?)
使用 CONVERT(datetime, '09.01.2018', 104)
。最好不要在查询中使用文字和魔术 strings/numbers - 将这些值放入变量中并像这样使用它们:
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)
如果您想要 select 具有两个日期值之间的日期且不在另一个 table 中的行,首先 select 使用 Between .. and
中的行Where
子句并使用 Not Exists
.
省略属于其他 table 的日期
查询
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]
);
使用 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)
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 个带日期的表格。
我想 select #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
如何解决?
您编写查询的方式取决于表中的值。如果您已经知道要 select 的日期,您可以这样做:
where A.workDate between CAST('11.01.2018' as datetime) and CAST('12.01.2018' as datetime)
您可能想要的是 select 行,其中 left join
不匹配任何内容:
where B.workDate is null
A.Id=B.Id
- 连接谓词中的这个条件在逻辑上是 wrong/makes 没有意义。你说的是比较日期 - Id
会在这里做什么? where
中的 OR
部分也是如此。
正如你所说的你的工作:从#temp1 开始的日期除了从#temp2 开始的日期 - 它可以是 "translated" 从英语到 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
或"dates from #temp1 which do not exist in #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)
。 "Default" 日期 format 取决于设置,例如可以是
ddmmyy
德语yymmdd
ANSImmddyy
美国
因此此转换可能会产生不同的日期(09 月 01 日或 01 月 09 日?)
使用 CONVERT(datetime, '09.01.2018', 104)
。最好不要在查询中使用文字和魔术 strings/numbers - 将这些值放入变量中并像这样使用它们:
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)
如果您想要 select 具有两个日期值之间的日期且不在另一个 table 中的行,首先 select 使用 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]
);
使用 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)