【问题标题】:SQL Server between statement语句之间的 SQL Server
【发布时间】:2018-02-13 16:51:49
【问题描述】:

我有两列,年份和支付期(1、2、3、4...)。我正在绞尽脑汁试图弄清楚如何在这些基础上做一个介于两者之间的事情。

例如说我有:

2017      1
2017      2
2017      3
2017      4
-------------v   
2017      5
2017      6
...
2017      51
2017      52 (typically, not guaranteed to be 52 periods)
2018      1
2018      2
2018      3
2018      4
-------------^
2018      5
...

我想选择 2017 (5) 和 2018 (4) 之间的所有行,我该怎么做?我尝试了几种不同的方法,但无法弄清楚。通常支付周期是 1-52,但我不能指望它。

【问题讨论】:

  • 您的数据量大吗?是拥有简单的可维护代码更重要,还是优化查询以使用索引更重要?

标签: sql sql-server between


【解决方案1】:

一个选项

Select * 
 from YourTable
 Where ([Year]*100)+[PayPeriod] between 201705 and 201804

【讨论】:

    【解决方案2】:

    一般来说,你可以用两个条件来处理这个问题。

    declare @yr int = 2018, @period = 5;
    
    select * from t
    where
           yr = @yr     and period <= @period
        or yr = @yr - 1 and period >= @period
    

    我不知道您将如何度过截止期,但有许多方法可能是合适的:

    -- period number is supplied as an argument
    with lp(last_period) as (
        select 4
    )
    select yr, period
    from T cross join lp
    where
            yr = year(current_timestamp)     and period <= last_period 
        or  yr = year(current_timestamp) - 1 and period >= last_period;
    
    
    -- assumes the "last" row in the table is the cutoff
    with lp(last_period) as (
        select distinct first_value(period) over (order by yr desc, period desc)
        from T 
    )
    select yr, period
    from T cross join lp
    where
            yr >= year(current_timestamp) - 1
        and yr  = year(current_timestamp) or period >= last_period;
    
    
    -- calculates period based on current date??
    with lp(last_period) as (
        select datepart(week, current_timestamp)
    )
    select yr, period
    from T cross join lp
    where
            yr = year(current_timestamp)     and period <= last_period 
        or  yr = year(current_timestamp) - 1 and period >= last_period;
    

    【讨论】:

    • Typically the pay periods are 1-52, but I can't count on that.
    【解决方案3】:

    如果行数较少,我会选择@JohnCappelletti 的答案。它简单易懂。

    如果您有大量的行,并且需要优化查询以使用索引,那么您希望避免对正在搜索的字段进行计算(同时避免OR 条件)。因此,我会使用类似...

    SELECT * FROM yourTable WHERE yr = 2016 AND period >= 5
    UNION ALL
    SELECT * FROM yourTable WHERE yr = 2017 AND period <  5
    

    确实,我建议更改表格的结构。正如您发现的那样,当您将比例分隔到两个字段时,在一个范围内进行过滤是“尴尬的”。

    一种选择是使用DATE 字段来表示每个支付期的开始。

    或者也许每个报告期都有一个单独的表格...

    CREATE TABLE dim_pay_period (
      id               INT IDENTITY(1,1),
      start_date       DATE,
      year             INT,
      period           INT,          -- The 1-52(ish) that you're using
      year_period      INT,          -- 201705, for example
      num_working_days INT           -- Just an example...
    )
    

    然后,您的数据表将有一个“pay_year_period”列,如果您需要查找有关该 year_period 的信息,您可以直接加入维度表。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2019-03-17
      • 2023-03-17
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多