【问题标题】:Conditional SQL date parameters to skip weekend days用于跳过周末的条件 SQL 日期参数
【发布时间】:2018-05-23 18:19:53
【问题描述】:

SQL 新手,对此我完全迷失了。尝试编写查询以提取前一天开设的新帐户,这在周二至周五很容易做到。但是在星期一它是星期天,我所尝试的一切都出错了。

这是我最接近的,但在最后一行仍然是错误的。我想我正在尝试应用 excel vba 类型逻辑,它只是不喜欢我。有人可以看看吗?

谢谢!

SELECT
    PortfolioCode as "Account", 
    f.reportheading1 as "Name", 
    d.portfoliostatus as "Status", 
    e.investmentstrategy as "Strategy",
    e.brokersource as "Broker", 
    e.referringfirm as "RefBy", 
    e.custodian as "Bank",
    e.manager as "Manager", 
    e.administrator as "APM", 
    d.initialvalue as "Open Value", 
    b.StartDate as "Start Date", 
    e.percentcash as "Cash%", 
    e.targetmvequity as "Eqt Trgt", 
    e.targetmvfixed as "FI Trgt", 
    e.munistrategy as "Muni Strat", 
    e.nationalmuni as "Nat. Muni", 
    e.statemunistrategy as "State Strat.", 
    e.residency as "Residency"
FROM
    AdvPortfolioBaseExt as A
INNER JOIN
    AdvPortfoliobase AS B ON A.PortfolioBaseID = b.PortfolioBaseID
INNER JOIN
    advportfolio AS C ON A.PortfolioBaseID = c.PortfolioID
INNER JOIN
    advapp.vportfolio AS D ON A.PortfolioBaseID = D.PortfolioID
INNER JOIN
    advportfoliobaseext AS E ON A.portfoliobaseid = e.portfoliobaseID
INNER JOIN
    advapp.vportfoliobase AS F ON a.PortfolioBaseID = f.PortfolioBaseID
WHERE 
    c.portfoliostatus <> 'Closed'
    AND IIF(DATEPART(dw, GETDATE()) = 2, b.startdate > GETDATE() - 3, b.startdate > GETDATE()-1)

【问题讨论】:

  • 作为一般性能问题,不看你问题的细节,你应该调用一次GetDate(),并存储它的值,否则每次被引用都会调用。

标签: sql-server tsql date conditional


【解决方案1】:

DATEPART(dw) 取决于服务器设置 DATEFIRST 的值。所以,我避免它......

WHERE
    b.startdate
    >=
    getdate() - CASE DATENAME(dw, getdate()) WHEN 'Sunday' THEN 2
                                             WHEN 'Monday' THEN 3
                                                           ELSE 1 END

另外,您的错误是因为来自IIF() 的返回值不能是逻辑比较的结果。它必须返回 SQL Server 中存在的类型的标量 fvalue(没有布尔类型)

这是有效的...

WHERE s.startdate >= IIF(x = y, a, b)

这是无效的...

WHERE IIF(x = y, s.startdate >= a, s.startdate >= b)


所以,你写的可能是……

WHERE
  s.startDate > IIF(datepart(dw,getdate()) = 2, getdate()-3, getdate()-1)

不过,如果在周日执行,那就错了……

【讨论】:

  • 您更愿意避免使用DatePart( dw ),因为它取决于DateFirst 的设置,然后选择取决于Language 设置的替代方案。无论DateFirstLanguage 的设置如何,( @@DateFirst + DatePart( weekday, SampleDate ) - 1 ) % 7 + 1 将始终返回一个从17 的整数,其中1 对应于星期日。
【解决方案2】:

这可能有点矫枉过正,但您可能希望参数化查询然后传递日期值。否则我只会做一个简单的 CTE 并设置一个日期时间变量,该变量将用于 where 条件。下面的 SQL 是针对 2005 的(较新的版本有不同的功能)。我不确定您使用的是哪个版本,所以我选择了最低公分母。无论如何,这应该可以工作,如果有索引字段,它们将不会受到您正在尝试的 WHERE 子句中的计算条件的影响。

DECLARE @Date DATETIME;

;WITH WeekDayOffset AS (
    SELECT 1 as WkDay, -2 as OffSet 
    UNION ALL 
    SELECT 2 as WkDay, 0 as OffSet 
    UNION ALL 
    SELECT 3 as WkDay, 0 as OffSet 
    UNION ALL 
    SELECT 4 as WkDay, 0 as OffSet 
    UNION ALL 
    SELECT 5 as WkDay, 0 as OffSet 
    UNION ALL 
    SELECT 6 as WkDay, 0 as OffSet 
    UNION ALL 
    SELECT 7 as WkDay, -1 as Offset
)

SELECT  @Date = CAST(CONVERT(VARCHAR(10), DATEADD(DAY, Offset, GETDATE()),101) AS datetime)
FROM WeekDayOffset
WHERE WkDay = DATEPART(dw, GETDATE())


SELECT
    PortfolioCode as "Account", 
    f.reportheading1 as "Name", 
    d.portfoliostatus as "Status", 
    e.investmentstrategy as "Strategy",
    e.brokersource as "Broker", 
    e.referringfirm as "RefBy", 
    e.custodian as "Bank",
    e.manager as "Manager", 
    e.administrator as "APM", 
    d.initialvalue as "Open Value", 
    b.StartDate as "Start Date", 
    e.percentcash as "Cash%", 
    e.targetmvequity as "Eqt Trgt", 
    e.targetmvfixed as "FI Trgt", 
    e.munistrategy as "Muni Strat", 
    e.nationalmuni as "Nat. Muni", 
    e.statemunistrategy as "State Strat.", 
    e.residency as "Residency"
FROM
    AdvPortfolioBaseExt as A
INNER JOIN
    AdvPortfoliobase AS B ON A.PortfolioBaseID = b.PortfolioBaseID
INNER JOIN
    advportfolio AS C ON A.PortfolioBaseID = c.PortfolioID
INNER JOIN
    advapp.vportfolio AS D ON A.PortfolioBaseID = D.PortfolioID
INNER JOIN
    advportfoliobaseext AS E ON A.portfoliobaseid = e.portfoliobaseID
INNER JOIN
    advapp.vportfoliobase AS F ON a.PortfolioBaseID = f.PortfolioBaseID
WHERE 
    c.portfoliostatus <> 'Closed'
    AND b.startdate > @Date

【讨论】:

    猜你喜欢
    • 2019-07-04
    • 1970-01-01
    • 2017-06-03
    • 2014-10-09
    • 1970-01-01
    • 1970-01-01
    • 2010-11-19
    • 2017-03-03
    • 1970-01-01
    相关资源
    最近更新 更多