【问题标题】:LAG of MIN in SQL AnalyticSQL 分析中 MIN 的 LAG
【发布时间】:2016-02-09 22:59:27
【问题描述】:

我有一个包含员工 ID、年份 ID、客户 ID 和销售数量的表格。例如:

 --------------------------------------
  id_emp | id_year | sales | client id
 --------------------------------------
    4    |    1    |   14  |    1
    4    |    1    |   10  |    2
    4    |    2    |   11  |    1
    4    |    2    |   17  |    2

对于一名员工,我想获取具有每年最低销售额和上一年最低销售额的行。

我尝试的查询之一如下:

select distinct 
  id_emp,
  id_year, 
  MIN(sales) OVER(partition by id_emp, id_year) AS min_sales,
  LAG(min(sales), 1) OVER(PARTITION BY id_emp, id_year
                              ORDER BY id_emp, id_year) AS previous
 from facts
where id_emp = 4
group by id_emp, id_year, sales;

我得到了结果:

 -------------------------------------    
  id_emp | id_year | sales | previous
 -------------------------------------
    4    |    1    |   10  |  (null)
    4    |    1    |   10  |    10
    4    |    2    |   11  |  (null)

但我希望得到:

 -------------------------------------
  id_emp | id_year | sales | previous
 -------------------------------------
    4    |    1    |   10  |  (null)
    4    |    2    |   11  |    10

【问题讨论】:

  • 您使用的是 Oracle 还是 Microsoft SQL Server?
  • 如果要得到上一年,为什么要在LAG函数中按年分区?

标签: sql-server oracle oracle11g analytics window-functions


【解决方案1】:

你的意思是这样的?

select id_emp, id_year, min(sales) as min_sales,
    lag(min(sales)) over (partition by id_emp order by id_year) as prev_year_min_sales
from facts
where id_emp = 4
group by id_emp, id_year;

【讨论】:

    【解决方案2】:

    SQL Fiddle

    Oracle 11g R2 架构设置

    CREATE TABLE EMPLOYEE_SALES ( id_emp, id_year, sales, client_id ) AS
              SELECT 4, 1, 14, 1 FROM DUAL
    UNION ALL SELECT 4, 1, 10, 2 FROM DUAL
    UNION ALL SELECT 4, 2, 11, 1 FROM DUAL
    UNION ALL SELECT 4, 2, 17, 2 FROM DUAL;
    

    查询 1

    SELECT ID_EMP,
           ID_YEAR,
           SALES AS SALES,
           LAG( SALES ) OVER ( PARTITION BY ID_EMP ORDER BY ID_YEAR ) AS PREVIOUS
    FROM   (
      SELECT e.*,
             ROW_NUMBER() OVER ( PARTITION BY id_emp, id_year ORDER BY sales ) AS RN
      FROM   EMPLOYEE_SALES e
    )
    WHERE rn = 1
    

    查询 2

    SELECT ID_EMP,
           ID_YEAR,
           MIN( SALES ) AS SALES,
           LAG( MIN( SALES ) ) OVER ( PARTITION BY ID_EMP ORDER BY ID_YEAR ) AS PREVIOUS
    FROM   EMPLOYEE_SALES
    GROUP BY ID_EMP, ID_YEAR
    

    Results - 两者输出相同

    | ID_EMP | ID_YEAR | SALES | PREVIOUS |
    |--------|---------|-------|----------|
    |      4 |       1 |    10 |   (null) |
    |      4 |       2 |    11 |       10 |
    

    【讨论】:

      【解决方案3】:

      您可以使用 ROW_NUMBER()LAG() 分析函数获得所需的输出。

      例如,

      表格

      SQL> SELECT * FROM t;
      
          ID_EMP    ID_YEAR      SALES  CLIENT_ID
      ---------- ---------- ---------- ----------
               4          1         14          1
               4          1         10          2
               4          2         11          1
               4          2         17          2
      

      查询

      SQL> WITH DATA AS
        2    (SELECT t.*,
        3      row_number() OVER(PARTITION BY id_emp, id_year ORDER BY sales) rn
        4    FROM t
        5    )
        6  SELECT id_emp,
        7    id_year ,
        8    sales ,
        9    lag(sales) over(order by sales) previous
       10  FROM DATA
       11  WHERE rn =1;
      
          ID_EMP    ID_YEAR      SALES   PREVIOUS
      ---------- ---------- ---------- ----------
               4          1         10
               4          2         11         10
      

      【讨论】:

        【解决方案4】:

        我相信这是因为您在 group by 语句中使用了销售列。 尝试删除它并使用

          GROUP BY id_emp,id_year
        

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2018-12-12
          • 1970-01-01
          • 2021-10-11
          • 2016-02-28
          相关资源
          最近更新 更多