collect_set 如何有序

  • 一、问题描述
  • 二、探索流程&解决
    • 2.1 数据
    • 2.2 初始sql

一、问题描述

需求简述:有一张日度表,需要按照需求方要求去实现,其他逻辑暂时不讨论,其中会涉及一个月度聚合某字段,并去重复,且按照dt asc 排序
环境:spark sql 2.4.0

二、探索流程&解决

2.1 数据

   SELECT 3517977374903924421 AS product_id,'03年线下批发经验,严选品质,赠送运费险' AS recommend_remark,"2022-02-03" AS dtUNION ALL SELECT 3517977374903924421 AS product_id,'下批发经验,严选品质,赠送运费险09年' AS recommend_remark,"2022-02-09" AS dtUNION ALL SELECT 3517977374903924421 AS product_id,'线下批发经验,严选品质,赠送运费险23年' AS recommend_remark,"2022-02-23" AS dtUNION ALL SELECT 3517977374903924421 AS product_id,'严选品质,赠送运费险,13年线下批发经验,' AS recommend_remark,"2022-02-13" AS dtUNION ALL SELECT 3517977374903924421 AS product_id,'赠送运费险04' AS recommend_remark,"2022-02-04" AS dt

2.2 初始sql

最初想用collect_set 直接处理然后子查询中排下序解决,这里用的pyspark sql 实现,没调用api 的方式,所以直接展示sql 了。
1)最初的sql

-- 造数据,假设表为all_data
WITH all_data AS( SELECT 3517977374903924421 AS product_id,'03年线下批发经验,严选品质,赠送运费险' AS recommend_remark,"2022-02-03" AS dtUNION ALL SELECT 3517977374903924421 AS product_id,'下批发经验,严选品质,赠送运费险09年' AS recommend_remark,"2022-02-09" AS dtUNION ALL SELECT 3517977374903924421 AS product_id,'线下批发经验,严选品质,赠送运费险23年' AS recommend_remark,"2022-02-23" AS dtUNION ALL SELECT 3517977374903924421 AS product_id,'严选品质,赠送运费险,13年线下批发经验,' AS recommend_remark,"2022-02-13" AS dtUNION ALL SELECT 3517977374903924421 AS product_id,'赠送运费险04' AS recommend_remark,"2022-02-04" AS dt),datas AS( SELECT product_id,recommend_remark,dtFROM all_dataWHERE dt>='2022-02-01'AND dt<'2022-03-01'AND product_id = 3517977374903924421ORDER BY dt ASC)
SELECT product_id,collect_set(recommend_remark) recommend_remark_list
FROM datas
GROUP BY product_id

2)运行截图

3)问题
子查询中加了一个 dt asc 排序,但collect_set 后依旧内部无序…

4)解决
看了下hive 函数中有一个 sort_array 方法。发现其可以排序但是是根据内容自然序的方式。原本想自己重写一个带排序的自定义collect_set 方法,所以去看了下collect_set 实现,发现底层用了LinkHashSet实现,也就是说要想有序必须是输入元素顺序有序。那也就是说不能使用全局order 排序。改换为 distribute by product_id sort by dt asc ,发现依旧没有解决问题,倒是这么操作后collect_list 是有序的了,但是在hive on spark 1.6版本测试是成功的!,后为了快速解决直接写了一个udf 去对collect_list后的数据进行去重复的操作,这里是用python 实现。

from pyspark.sql.types import ArrayType,StringType
import jsondef get_array_set(col_list):new_list = []if col_list:try:for x in col_list:if x not in new_list:new_list.append(x)except:print("数据json异常:" + str_json)return []return new_listget_array_set = spark.udf.register('get_array_set', get_array_set, ArrayType(StringType()))

然后sql 改为

WITH all_data AS(SELECT 3517977374903924421 AS product_id,'03年线下批发经验,严选品质,赠送运费险' AS recommend_remark,"2022-02-03" AS dtUNION ALL SELECT 3517977374903924421 AS product_id,'下批发经验,严选品质,赠送运费险09年' AS recommend_remark,"2022-02-09" AS dtUNION ALL SELECT 3517977374903924421 AS product_id,'线下批发经验,严选品质,赠送运费险23年' AS recommend_remark,"2022-02-23" AS dtUNION ALL SELECT 3517977374903924421 AS product_id,'严选品质,赠送运费险,13年线下批发经验,' AS recommend_remark,"2022-02-13" AS dtUNION ALL SELECT 3517977374903924421 AS product_id,'赠送运费险04' AS recommend_remark,"2022-02-04" AS dtUNION ALL SELECT 3517977374903924421 AS product_id,'赠送运费险03' AS recommend_remark,"2022-02-03" AS dtUNION ALL SELECT 3517977374903924421 AS product_id,'赠送运费险03' AS recommend_remark,"2022-02-01" AS dt),datas AS( SELECT product_id,concat('"',recommend_remark,'"') as recommend_remark1,dtFROM all_dataWHERE dt>='2022-02-01'AND dt<'2022-03-01'distribute by product_idsort by dt asc)
SELECT product_id,get_array_set(collect_list(recommend_remark1)) recommend_remark_list
FROM datas
GROUP BY product_id

5)最终运行结果

collect_set 如何有序相关推荐

  1. Redis 笔记(07)— sorted set 类型(添加、删除有序集合元素、获取分数范围内成员、按score排序、返回集合元素个数)

    zset 可能是 Redis 提供的最为特色的数据结构,一方面它是一个 set,保证了内部 value 的唯一性,另一方面它可以给每个 value 赋予一个 score,代表这个 value 的排序权 ...

  2. LeetCode简单题之有序数组中出现次数超过25%的元素

    题目 给你一个非递减的 有序 整数数组,已知这个数组中恰好有一个整数,它的出现次数超过数组元素总数的 25%. 请你找到并返回这个整数 示例: 输入:arr = [1,2,2,6,6,6,6,7,10 ...

  3. LeetCode简单题之有序数组的平方

    题目 给你一个按 非递减顺序 排序的整数数组 nums,返回 每个数字的平方 组成的新数组,要求也按 非递减顺序 排序. 示例 1: 输入:nums = [-4,-1,0,3,10] 输出:[0,1, ...

  4. [C++] 牛客网:合并两个有序的数组

    主要是体验一下牛客网里的核心代码模式到底是怎么弄的..还有C++这个东西平常用的太少了,试一试. 以外的还体验到了sort()函数的使用. 来源:牛客网 题目链接:合并两个有序的数组 知识点:数组.双 ...

  5. Go 学习笔记(12)— 字典map定义、初始化、读取字典、删除字典、清空字典、map 按 key 进行有序遍历

    Go 中字典也叫做 map , map 是一种无序的键值对的集合. map 最重要的一点是通过 key 来快速检索数据, key 类似于索引,指向数据的值. 1. 字典定义 可以使用内建函数 make ...

  6. python有序队列_Python 队列

    所谓队列 队列是有序集合,添加操作发生在"尾部",移除操作则发生在"头部". 新元素从尾部进入 队列,然后一直向前移动到头部,直到成为下一个被移除的元素. 新添 ...

  7. 数据结构与算法(8-2)有序表查找(折半查找(二分查找)、插值查找)

    目录 一.折半查找(二分查找) 二.插值查找 总代码 一.折半查找(二分查找) 原理:一次次折半,不断向着查找值的位置靠近 . 适用场景:有序(必须) 流程:开始时,min标志首,max标志尾,med ...

  8. 【力扣网练习题】合并两个有序链表

    将两个有序链表合并为一个新的有序链表并返回.新链表是通过拼接给定的两个链表的所有节点组成的. 示例:输入:1->2->4, 1->3->4 输出:1->1->2-& ...

  9. leetcode-21 合并两个有序链表

    将两个有序链表合并为一个新的有序链表并返回.新链表是通过拼接给定的两个链表的所有节点组成的. 示例: 输入:1->2->4, 1->3->4 输出:1->1->2- ...

最新文章

  1. 浅析.Net下的AppDomain编程
  2. 固态硬盘驱动器在设计上有个安全漏洞 易导致数据损毁
  3. linux suse10虚拟机在静态IP局域网中如何设置桥接上网
  4. mysql 录入窗体设计_在Access中,可用于设计输入界面的对象是   A)窗体 B)报表 C)查询 D)表...
  5. 3.6 权值初始化-机器学习笔记-斯坦福吴恩达教授
  6. python文档生成工具_pydoc --- 文档生成器和在线帮助系统 — Python 3.9.1rc1 文档
  7. C#使用Win32API获得窗口和控件的句柄
  8. apache wicket_Apache Wicket:记住我的功能
  9. 蓝桥杯评分标准_蓝桥杯比赛要求
  10. 计算机数学基础模拟试题,计算机数学基础》模拟考试试题.doc
  11. java I O类大全_Java I/O最简单的几个类
  12. 【HDU - 2200】Eddy's AC难题(简单组合数学)
  13. nginx访问日志常用变量
  14. 如何选择WEB报表工具(二)
  15. cuSPARSE库:(十二)cusparseDestroyMatDescr()
  16. 英寸和厘米的换算python_OJ实例:厘米换算英尺英寸
  17. 【考研】数据库知识点总结
  18. ENSP未找到base device,是否立即注册
  19. Putty(菩提)远程连接服务器教程听语音
  20. 本地部署你的专属ChatGPT,不用想方设法翻墙了

热门文章

  1. 必须掌握sprintf函数的用法
  2. 【ROS程序显示中文】
  3. 查缺补漏的一些知识点
  4. 百度2021校招C /PHP研发工程师笔试卷(第一批)
  5. Elasitcsearch 开发运维常用命令集锦
  6. 五.QT cmake无法建立新文件的解决方法
  7. UML九种标准图详解
  8. MySQL免安装版安装探索
  9. 将爱好变为职业:游戏配乐与声音设计
  10. Unity 游戏Demo制作 地下城 二