如何得到一个月的最后一天不同的项目sql语句

30byixjq  于 2021-06-25  发布在  Hive
关注(0)|答案(5)|浏览(411)

我应该有一些样本数据在里面 table_name_a 具体如下:

  1. code val_a date
  2. -------------------------
  3. 1 00001 500 20191101
  4. 2 00001 1000 20191130
  5. 3 00002 200 20191101
  6. 4 00002 400 20191130
  7. 5 00003 200 20191101
  8. 6 00003 600 20191130

有一些 val_acode 在20191101和20191130之间,我想得到每个月的最后一天值 code ,我的sql查询如下(需要匹配 Hive 以及 Impla ):

  1. SELECT code, max(date) AS date, val_a
  2. FROM table_a
  3. WHERE date BETWEEN '20090601'
  4. AND '20090630'
  5. GROUP BY code, val_a

但是上面的查询是错误的(代码的值不是这个月的最后一天),我的预期输出如下:

  1. code val_a date
  2. --------------------------
  3. 1 00001 1000 20191130
  4. 2 00002 400 20191130
  5. 3 00003 600 20191130

非常感谢你的建议。

iugsix8n

iugsix8n1#

如果您只需要每月最后一天的数据,那么您可以使用 LAST_DAY 以及 TRUNC 函数在中的日期 WHERE 条款如下:

  1. SELECT
  2. CODE,
  3. DATE AS "DATE", -- removed MAX
  4. VAL_A
  5. FROM
  6. TABLE_A
  7. WHERE
  8. DATE BETWEEN '20090601' AND '20090630'
  9. AND TRUNC(LAST_DAY(MAX(DATE))) = TRUNC(DATE); -- added this condition
  10. -- removed the GROUP BY clause

干杯!!

j0pj023g

j0pj023g2#

您可以尝试以下代码。在子查询中,您将获得最大日期和代码。这个 WHERE IN 子句用作数据的筛选器。

  1. SELECT code, val_a, date
  2. FROM table_a
  3. WHERE (code, date) IN
  4. (SELECT code, MAX(date)
  5. FROM table_a
  6. GROUP BY code)
uwopmtnx

uwopmtnx3#

更一般地说,您可以使用正确的子查询:

  1. select a.*
  2. from table_a a
  3. where a.date = (select max(a1.date) from table_a a1 where a1.code = a.code);
cbwuti44

cbwuti444#

使用行号:

  1. with your_data as (
  2. select stack(6,
  3. '00001',500 ,'20191101',
  4. '00001',1000,'20191130',
  5. '00002',200 ,'20191101',
  6. '00002',400 ,'20191130',
  7. '00003',200 ,'20191101',
  8. '00003',600 ,'20191130' ) as (code,val_a,date)
  9. )
  10. select code,val_a,date
  11. from
  12. (
  13. select code,val_a,date,
  14. --partition by code and months, max date first
  15. row_number() over(partition by code, substr(date, 1,6) order by date desc) rn
  16. from your_data d
  17. )s where rn=1
  18. ;

结果:

  1. OK
  2. code val_a date
  3. 00001 1000 20191130
  4. 00002 400 20191130
  5. 00003 600 20191130
  6. Time taken: 54.641 seconds, Fetched: 3 row(s)
展开查看全部
v09wglhw

v09wglhw5#

我们可以试着用 ROW_NUMBER 解决方案:

  1. WITH cte AS (
  2. SELECT t.*, ROW_NUMBER() OVER (PARTITION BY code ORDER BY date DESC) rn
  3. FROM table_a
  4. -- WHERE date BETWEEN '20090601' AND '20090630'
  5. -- your current WHERE clause is dubious
  6. )
  7. SELECT code, date, val_a
  8. FROM cte
  9. WHERE rn = 1;

请注意,将日期存储为文本不是最佳做法。也就是说,假设您是以固定宽度的iso格式存储日期,在这种情况下,我们仍然可以使用这些日期。还有,你现在 WHERE 子句没有意义,所以我把它注解掉了。

相关问题