将Tertile连接到四分之一SQL(4个月至3个月)

时间:2019-06-24 16:34:21

标签: sql sql-server

假设我们每年以三分位数(三个月四个月)测量一次海龟的外观三次。然后,我们切换到季度(四个3个月的周期)。我想将本年度的值与上一年的值进行比较。

感谢史蒂夫的评论。最初,我在4个月内使用了错误的单词,称为“三个月”。这四个月期间的正确单词是tertile or quadrimester

+------+--------+------------+------------+----------+
| year | period |     d1     |     d2     | value_cy |
+------+--------+------------+------------+----------+
| 2018 | T1     | 2018-01-01 | 2018-04-01 |       10 |
| 2018 | T2     | 2018-05-01 | 2018-08-01 |       20 |
| 2018 | T3     | 2018-09-01 | 2018-12-01 |       30 |
| 2019 | Q1     | 2019-01-01 | 2019-03-01 |       18 |
| 2019 | Q2     | 2019-04-01 | 2019-06-01 |       16 |
| 2019 | Q3     | 2019-07-01 | 2019-09-01 |       14 |
| 2019 | Q4     | 2019-10-01 | 2019-12-01 |       12 |
+------+--------+------------+------------+----------+

这是预期的结果:

+------+--------+------------+------------+----------+----------+
| year | period |     d1     |     d2     | value_cy | value_py |
+------+--------+------------+------------+----------+----------+
| 2018 | T1     | 2018-01-01 | 2018-04-01 |       10 |          |
| 2018 | T2     | 2018-05-01 | 2018-08-01 |       20 |          |
| 2018 | T3     | 2018-09-01 | 2018-12-01 |       30 |          |
| 2019 | Q1     | 2019-01-01 | 2019-03-01 |       18 |      7.5 |
| 2019 | Q2     | 2019-04-01 | 2019-06-01 |       16 |     12.5 |
| 2019 | Q3     | 2019-07-01 | 2019-09-01 |       14 |     17.5 |
| 2019 | Q4     | 2019-10-01 | 2019-12-01 |       12 |     22.5 |
+------+--------+------------+------------+----------+----------+
where
    Q1=3/4 * T1
    Q2=1/4 * T1 + 1/2 * T2 

我的努力:

我想到的是一个中间表,该表将三个月的周期转换成几个月,然后再转换成季度。

+--------+-------+
| period | month |
+--------+-------+
| Q1     |     1 |
| Q1     |     2 |
| Q1     |     3 |
| Q2     |     4 |
| Q2     |     5 |
| Q2     |     6 |
| Q3     |     7 |
| Q3     |     8 |
| Q3     |     9 |
| Q4     |    10 |
| Q4     |    11 |
| Q4     |    12 |
| T1     |     1 |
| T1     |     2 |
| T1     |     3 |
| T1     |     4 |
| T2     |     5 |
| T2     |     6 |
| T2     |     7 |
| T2     |     8 |
| T3     |     9 |
| T3     |    10 |
| T3     |    11 |
| T3     |    12 |
+--------+-------+

但是我想知道是否可以通过源表的两个自联接来完成,第一次联接等于或早于最近的日期,第二次联接等于或晚于日期。有了这两个日期及其与原始日期的差异,我们可以计算结果。

1 个答案:

答案 0 :(得分:0)

假设您不想在以后的三个月中继续记录数据(即,可以通过一次操作解决此问题),并且您正在使用SQL Server,则可以将每个月的中期数据预处理为一个季度首先将数据放在同一张表中,以便您进行比较。类似以下内容将为您提供Q1和Q2值:

-- Q1 rows
INSERT INTO data_table (year, period, d1, d2, value_cy)
SELECT year, period, d1, d2, t1_component.value_cy FROM
(
    SELECT
        year,
        'Q1' AS period,
        CONCAT(year, '-01-01') AS d1,
        CONCAT(year, '-04-01') AS d2,
    FROM
        data_table
) main
CROSS APPLY
(
    SELECT 0.75 * value_cy AS value_cy
    FROM data_table
    WHERE year = main.year
    AND period = 'T1'
) t1_component;

-- Q2 rows
INSERT INTO data_table (year, period, d1, d2, value_cy)
SELECT year, period, d1, d2, t1_component.value_cy + t2_component.value_cy FROM
(
    SELECT
        year,
        'Q2' AS period,
        CONCAT(year, '-05-01') AS d1,
        CONCAT(year, '-08-01') AS d2,
    FROM
        data_table
) main
CROSS APPLY
(
    SELECT 0.25 * value_cy AS value_cy
    FROM data_table
    WHERE year = main.year
    AND period = 'T1'
) t1_component
CROSS APPLY
(
    SELECT 0.5 * value_cy AS value_cy
    FROM data_table
    WHERE year = main.year
    AND period = 'T2'
) t2_component;

您可以根据需要通过调整上述查询来获取Q3和Q4值。一旦所有值都以季度格式显示,就可以进行自我联接以获取上一年的结果和本年度的结果,尽管由于必须联接计算值,这会很慢(尽管这可能满足您的需求) :

SELECT
    cy.year,
    cy.period,
    cy.d1,
    cy.d2,
    cy.value_cy,
    py.value_cy AS value_py
FROM data_table cy
INNER JOIN data_table py
    ON py.year-1 = cy.year
WHERE cy.period IN ('Q1', 'Q2', 'Q3', 'Q4')

或者,您可以看看PIVOT运算符,该运算符基本上可以转换列标题中的行值:

 SELECT period, [2019], [2018]
 FROM
     (SELECT period, year, value_cy FROM data_table WHERE period IN ('Q1', 'Q2', 'Q3', 'Q4')) AS src
 PIVOT
     (value_cy FOR year IN ([2019], [2018])
 AS pivotTable