我的 SQL - 如何 运行 在不同的工作日使用不同的 WHERE 语句,比如一个用于星期一,另一个用于星期五
My SQL - How to run different WHERE statements on different weekdays, like one for monday and another for friday
我误解了很多,再次感谢所有帮助。
我最终为我的案例找到了解决方案,它甚至不涉及任何类似
如果星期一那么 SELECT
我什至不需要 CASE 语句。
我必须做的是在不同的 WHERE 语句之间放置一个 OR。
我已经在下面陈述了我的最终代码:
SELECT * FROM
(SELECT
t.pay_date
, t.supp_name
, t.client AS row_client
, t.ip_status
, t.bank_account
, t.remitt_curr AS remitt_curr
, t.remitt_id
, t.apar_id
, t.payment_id
FROM
aipheader t
WHERE
DATEPART(DW, GETDATE()) IN (2,3,4)
AND
t.pay_date BETWEEN '2019-01-01' AND DATEADD(DAY,-4,GETDATE())
OR
DATEPART(DW, GETDATE()) IN (5,6)
AND
t.pay_date BETWEEN '2019-01-01' AND DATEADD(DAY,-2,GETDATE())) x
ORDER BY 1
上面的语句将执行正确的 OR 块,在我的例子中是正确的工作日。
********* 下面是老问题 ***********
我想 运行 在一周的不同休息日进行不同的 SELECT 陈述。
我实际上可以让下面的代码工作:
select
case
when DATEPART(DW, GETDATE()) = 4 then
(select 'HELLO' )
ELSE
(select 'GOODBYE')
end
在星期三 returns "HELLO" 上面的代码,每隔一个工作日它会 returns "Goodbye"。到目前为止一切顺利!
只要 select 语句只有 return 一个值就可以工作,但我真的想要一个完整的 table 如下所示。
这里唯一的区别应该是 [* FROM table] 部分,它打破了一切:
select
case
when DATEPART(DW, GETDATE()) = 4 then
(select * FROM table1)
ELSE
(select * FROM table2)
end
如果我什至不能让上面的工作正常工作,我就不能为不同的工作日做不同的 SELECT,所以这很难弄清楚。
我试过用 () 封装一些东西,并以不同的方式添加一些 SELECT 但它不起作用,所以它可能是一些 SQL 主体。
我收到一条错误消息,我认为如果只有一个值 returned:
就可以了
SqlState 37000 Native 116 [Microsoft][ODBC SQL Server Driver][SQL
Server]Only one expression can be specified in the select list when
the subquery is not introduced with EXISTS.
感谢所有回复,我现在理解得更好了。
我不想添加专栏,我想我可以做一个全新的 SELECT 声明。正如您所指出的,我现在看到我的 CASE 语句只添加了一列。
那么我的第一个 ide 可能是一个更好的过程,实际修改 select 语句中的 WHERE 子句。
我现在已经尝试过了,但它不起作用。
SELECT * FROM aipheader t
WHERE
CASE
WHEN DATEPART(DW, GETDATE()) = 4 THEN
t.pay_date = '2019-10-15'
ELSE
t.pay_date = '2019-10-17'
END
它 return 是错误:
SqlState 37000 Native 102 [Microsoft][ODBC SQL Server Driver][SQL
Server]Incorrect syntax near '='.
我试过更简单的:
SELECT * FROM aipheader t
WHERE
t.pay_date BETWEEN DATEADD(DAY,-120,GETDATE()) AND DATEADD(DAY,-5,GETDATE())
以上是一种更简单的形式,但 return 是正确的值。
但是上面那个带有 CASE 子句的那个 return 关于“=”-sign 的错误。
可能 WHERE 语句中的 CASE 部分不起作用。
我不完全明白你想要达到的目的。
当然你的语句是行不通的,因为你的select
语句中有case when
returns多个列和行。这行不通,因为您的 case when
语句将显示 一列 !
所以你可以做的是:
select
case
when DATEPART(DW, GETDATE()) = 4 then
'HELLO'
ELSE
'GOODBYE'
end as [someField],
*
from
[table]
此查询会将 table
中的所有行和列作为输出 + someField
显示 HELLO
或 GOODBYE
。
如果您想在不同日期(星期三或非星期三)显示来自 table 的不同数据,您可以这样更改查询:
select
case
when DATEPART(DW, GETDATE()) = 4 then
[table].[field1]
ELSE
[table].[field2]
end as [someField],
*
from
[table]
你在找这个吗?子查询应该 return 1 行并指定列名
select
case
when DATEPART(DW, GETDATE()) = 4 then
(select top 1 col1 from table1 )
ELSE
(select top 1 col2 from table2 )
end as result
From table
CASE WHEN
只能 return 每个 THEN
的 单个值 ,并且 永远不会 具有多行 and/or 列的结果集。这就是 CASE WHEN
的工作原理。
你可以这样实现你所需要的:
DECLARE @DAY INT = DATEPART(DW, GETDATE())
select * FROM table
WHERE (@DAY = 4 AND table.SomeCol = SomeValue)
OR (@DAY = 5 AND table.SomeCol = SomeOtherValue)
... repeat for other days
或者像这样:
DECLARE @DAY INT = DATEPART(DW, GETDATE())
IF @DAY = 4
(select * FROM table WHERE table.SomeCol = SomeValue)
ELSE IF @DAY = 5
(select * FROM table WHERE table.SomeCol = SomeOtherValue)
... repeat for other days
或者像这样:
DECLARE @DAY INT = DATEPART(DW, GETDATE())
select * FROM table
WHERE @DAY = 4 AND table.SomeCol = SomeValue
UNION ALL
select * FROM table
WHERE @DAY = 5 AND table.SomeCol = SomeOtherValue
UNION ALL
... repeat for other days
我的偏好可能是第一种或第二种形式。
查询必须 return 已知列。如果表 table1
和 table2
有不同的列,你不能写一个查询 returns,比如说,一天表 1 的五列和另一天表 2 的九列。
但是,只要结果列保持不变,您就可以选择性地加入。这是一个小例子:
select
p.project_id,
p.project_name,
coalesce(c1.name, c2.name) as team_member,
coalesce(c1.salary, c2.salary * (1.0 + c2.tax / 100.0)) as team_member_salary,
coalesce(c1.job_name, c2.job_title) as team_member_job
from project p
left join crew1 c1 on c1.project_id = p.project_id and datepart(dw, getdate()) = 4
left join crew2 c2 on c2.project_id = p.project_id and datepart(dw, getdate()) <> 4
order by p.project_id;
不确定我是否真的理解您在这里想要实现的目标。此示例假定您正在根据日期从不同的表中读取数据,并将 return 来自两个表的所有行:
select * from (
select 'HELLO' as col1, * from table1 where DATEPART(DW, GETDATE()) = 4
UNION ALL
select 'GOODBYE' as col1, * from table2 where DATEPART(DW, GETDATE()) <> 4
)
order by col1
编辑后,过滤日期的正确方法如下:
SELECT
*
FROM
aipheader t
WHERE
t.pay_date = CASE WHEN DATEPART(DW, GETDATE()) = 4 THEN '2019-10-15' ELSE '2019-10-17' END
但是,您真的要对 2019-10-15
和 2019-10-17
日期进行硬编码吗?似乎这些应该随着时间的推移自动计算。
将 DATEPART
与 DW
一起使用时要小心,因为周数起点实际上可能会根据服务器的 and/or 当前会话设置而改变。检查这个例子:
DECLARE @TestDate DATE = '2020-01-01' -- Wednesday
SET DATEFIRST 1 -- 1: Monday, 7: Sunday
SELECT DATEPART(DW, @TestDate) -- Returns 3
SET DATEFIRST 7 -- 1: Sunday, 7: Saturday
SELECT DATEPART(DW, @TestDate) -- Returns 4!
因此,无论何时检查一周中的特定日期,请确保将 DATEFIRST
会话参数强制设置为特定值,以便与您的检查一致。
我误解了很多,再次感谢所有帮助。 我最终为我的案例找到了解决方案,它甚至不涉及任何类似 如果星期一那么 SELECT 我什至不需要 CASE 语句。
我必须做的是在不同的 WHERE 语句之间放置一个 OR。
我已经在下面陈述了我的最终代码:
SELECT * FROM
(SELECT
t.pay_date
, t.supp_name
, t.client AS row_client
, t.ip_status
, t.bank_account
, t.remitt_curr AS remitt_curr
, t.remitt_id
, t.apar_id
, t.payment_id
FROM
aipheader t
WHERE
DATEPART(DW, GETDATE()) IN (2,3,4)
AND
t.pay_date BETWEEN '2019-01-01' AND DATEADD(DAY,-4,GETDATE())
OR
DATEPART(DW, GETDATE()) IN (5,6)
AND
t.pay_date BETWEEN '2019-01-01' AND DATEADD(DAY,-2,GETDATE())) x
ORDER BY 1
上面的语句将执行正确的 OR 块,在我的例子中是正确的工作日。
********* 下面是老问题 ***********
我想 运行 在一周的不同休息日进行不同的 SELECT 陈述。
我实际上可以让下面的代码工作:
select
case
when DATEPART(DW, GETDATE()) = 4 then
(select 'HELLO' )
ELSE
(select 'GOODBYE')
end
在星期三 returns "HELLO" 上面的代码,每隔一个工作日它会 returns "Goodbye"。到目前为止一切顺利!
只要 select 语句只有 return 一个值就可以工作,但我真的想要一个完整的 table 如下所示。
这里唯一的区别应该是 [* FROM table] 部分,它打破了一切:
select
case
when DATEPART(DW, GETDATE()) = 4 then
(select * FROM table1)
ELSE
(select * FROM table2)
end
如果我什至不能让上面的工作正常工作,我就不能为不同的工作日做不同的 SELECT,所以这很难弄清楚。
我试过用 () 封装一些东西,并以不同的方式添加一些 SELECT 但它不起作用,所以它可能是一些 SQL 主体。
我收到一条错误消息,我认为如果只有一个值 returned:
就可以了SqlState 37000 Native 116 [Microsoft][ODBC SQL Server Driver][SQL Server]Only one expression can be specified in the select list when the subquery is not introduced with EXISTS.
感谢所有回复,我现在理解得更好了。
我不想添加专栏,我想我可以做一个全新的 SELECT 声明。正如您所指出的,我现在看到我的 CASE 语句只添加了一列。
那么我的第一个 ide 可能是一个更好的过程,实际修改 select 语句中的 WHERE 子句。
我现在已经尝试过了,但它不起作用。
SELECT * FROM aipheader t
WHERE
CASE
WHEN DATEPART(DW, GETDATE()) = 4 THEN
t.pay_date = '2019-10-15'
ELSE
t.pay_date = '2019-10-17'
END
它 return 是错误:
SqlState 37000 Native 102 [Microsoft][ODBC SQL Server Driver][SQL Server]Incorrect syntax near '='.
我试过更简单的:
SELECT * FROM aipheader t
WHERE
t.pay_date BETWEEN DATEADD(DAY,-120,GETDATE()) AND DATEADD(DAY,-5,GETDATE())
以上是一种更简单的形式,但 return 是正确的值。 但是上面那个带有 CASE 子句的那个 return 关于“=”-sign 的错误。
可能 WHERE 语句中的 CASE 部分不起作用。
我不完全明白你想要达到的目的。
当然你的语句是行不通的,因为你的select
语句中有case when
returns多个列和行。这行不通,因为您的 case when
语句将显示 一列 !
所以你可以做的是:
select
case
when DATEPART(DW, GETDATE()) = 4 then
'HELLO'
ELSE
'GOODBYE'
end as [someField],
*
from
[table]
此查询会将 table
中的所有行和列作为输出 + someField
显示 HELLO
或 GOODBYE
。
如果您想在不同日期(星期三或非星期三)显示来自 table 的不同数据,您可以这样更改查询:
select
case
when DATEPART(DW, GETDATE()) = 4 then
[table].[field1]
ELSE
[table].[field2]
end as [someField],
*
from
[table]
你在找这个吗?子查询应该 return 1 行并指定列名
select
case
when DATEPART(DW, GETDATE()) = 4 then
(select top 1 col1 from table1 )
ELSE
(select top 1 col2 from table2 )
end as result
From table
CASE WHEN
只能 return 每个 THEN
的 单个值 ,并且 永远不会 具有多行 and/or 列的结果集。这就是 CASE WHEN
的工作原理。
你可以这样实现你所需要的:
DECLARE @DAY INT = DATEPART(DW, GETDATE())
select * FROM table
WHERE (@DAY = 4 AND table.SomeCol = SomeValue)
OR (@DAY = 5 AND table.SomeCol = SomeOtherValue)
... repeat for other days
或者像这样:
DECLARE @DAY INT = DATEPART(DW, GETDATE())
IF @DAY = 4
(select * FROM table WHERE table.SomeCol = SomeValue)
ELSE IF @DAY = 5
(select * FROM table WHERE table.SomeCol = SomeOtherValue)
... repeat for other days
或者像这样:
DECLARE @DAY INT = DATEPART(DW, GETDATE())
select * FROM table
WHERE @DAY = 4 AND table.SomeCol = SomeValue
UNION ALL
select * FROM table
WHERE @DAY = 5 AND table.SomeCol = SomeOtherValue
UNION ALL
... repeat for other days
我的偏好可能是第一种或第二种形式。
查询必须 return 已知列。如果表 table1
和 table2
有不同的列,你不能写一个查询 returns,比如说,一天表 1 的五列和另一天表 2 的九列。
但是,只要结果列保持不变,您就可以选择性地加入。这是一个小例子:
select
p.project_id,
p.project_name,
coalesce(c1.name, c2.name) as team_member,
coalesce(c1.salary, c2.salary * (1.0 + c2.tax / 100.0)) as team_member_salary,
coalesce(c1.job_name, c2.job_title) as team_member_job
from project p
left join crew1 c1 on c1.project_id = p.project_id and datepart(dw, getdate()) = 4
left join crew2 c2 on c2.project_id = p.project_id and datepart(dw, getdate()) <> 4
order by p.project_id;
不确定我是否真的理解您在这里想要实现的目标。此示例假定您正在根据日期从不同的表中读取数据,并将 return 来自两个表的所有行:
select * from (
select 'HELLO' as col1, * from table1 where DATEPART(DW, GETDATE()) = 4
UNION ALL
select 'GOODBYE' as col1, * from table2 where DATEPART(DW, GETDATE()) <> 4
)
order by col1
编辑后,过滤日期的正确方法如下:
SELECT
*
FROM
aipheader t
WHERE
t.pay_date = CASE WHEN DATEPART(DW, GETDATE()) = 4 THEN '2019-10-15' ELSE '2019-10-17' END
但是,您真的要对 2019-10-15
和 2019-10-17
日期进行硬编码吗?似乎这些应该随着时间的推移自动计算。
将 DATEPART
与 DW
一起使用时要小心,因为周数起点实际上可能会根据服务器的 and/or 当前会话设置而改变。检查这个例子:
DECLARE @TestDate DATE = '2020-01-01' -- Wednesday
SET DATEFIRST 1 -- 1: Monday, 7: Sunday
SELECT DATEPART(DW, @TestDate) -- Returns 3
SET DATEFIRST 7 -- 1: Sunday, 7: Saturday
SELECT DATEPART(DW, @TestDate) -- Returns 4!
因此,无论何时检查一周中的特定日期,请确保将 DATEFIRST
会话参数强制设置为特定值,以便与您的检查一致。