我的 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 whenreturns多个列和行。这行不通,因为您的 case when 语句将显示 一列 !

所以你可以做的是:

select 
   case 
      when DATEPART(DW, GETDATE())  = 4 then 
         'HELLO'
      ELSE 
         'GOODBYE'
   end as [someField],
   *
from
   [table]

此查询会将 table 中的所有行和列作为输出 + someField 显示 HELLOGOODBYE。 如果您想在不同日期(星期三或非星期三)显示来自 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 已知列。如果表 table1table2 有不同的列,你不能写一个查询 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-152019-10-17 日期进行硬编码吗?似乎这些应该随着时间的推移自动计算。


DATEPARTDW 一起使用时要小心,因为周数起点实际上可能会根据服务器的 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 会话参数强制设置为特定值,以便与您的检查一致。