分组记录第一条(转)

1 --建立测试环境   
CREATE   TABLE   table1(a   VARCHAR(10),b   VARCHAR(10),c   VARCHAR(10));   

--插入数据   
INSERT   INTO table1 VALUES('2004','12','storea');

INSERT   INTO   table1 VALUES('2005','07','storea');   

INSERT   INTO   table1 VALUES('2004','11','storeb'); 

INSERT   INTO   table1 VALUES('2005','06','storeb');  
  
COMMIT;

2 取分组记录的第一条

解法一

SELECT   a.*   FROM   table1   a   INNER   JOIN   (   
SELECT   MAX(a   +   b)TIME   FROM   table1     
GROUP   BY   c   )   b   
ON   a.a   +   a.b   =   b.TIME

解法二

SELECT * FROM scott.table1 a WHERE NOT EXISTS
   (SELECT 1   FROM scott.table1 b WHERE a.a=b.a AND TO_NUMBER(a.b)<TO_NUMBER(b.b));

解法三

SELECT * FROM (SELECT t.*, RANK() 
        OVER (PARTITION BY t.a ORDER BY t.b DESC) AS drank
FROM table1 t) a WHERE drank=1

引申

SELECT t.*,SUM(b) OVER (PARTITION BY t.a) AS aaa,
   SUM(b) OVER () AS bbb
FROM table1 t
ORDER BY t.a,t.b

 

 

------

SELECT d.department_id , e.last_name, e.salary, RANK() 
        OVER (PARTITION BY e.department_id ORDER BY e.salary) AS drank
FROM employees e, departments d
WHERE e.department_id = d.department_id
   AND d.department_id IN ('60', '90');

http://www.cnblogs.com/ball-head/archive/2010/01/20/1652822.html

### ClickHouse 中分组第一条记录的方法 在 ClickHouse 中,可以通过 `LIMIT` 子句配合 `GROUP BY` 和其他辅助函数来实现分组后获第一条记录。以下是具体的解决方案: #### 方法一:使用 `LIMIT 1 BY` ClickHouse 提供了一个非常简洁的方式——`LIMIT 1 BY` 来实现这一需求。该方法可以直接指定按某个字段分组,并为每一保留一条记录。 ```sql SELECT user_id, school_id, device_sn, gmt_create FROM app_device_info WHERE gmt_create >= '2023-11-24 00:00:00' AND gmt_create <= '2023-11-25 00:00:00' ORDER BY gmt_create DESC LIMIT 1 BY user_id; ``` 这条 SQL 的作用是对表中的数据按照 `user_id` 进行分组,并为每个 `user_id` 只返回最新的那一条记录(基于 `gmt_create` 字段降序排列)。这种方法简单高效,适用于大多数场景[^5]。 --- #### 方法二:嵌套查询结合数操作 如果需要更复杂的逻辑处理,可以借助子查询和数操作完成目标。以下是一个通用的例子: ```sql SELECT course, arrayJoin(top_names) AS name, arrayJoin(top_scores) AS score FROM ( SELECT course, groupArray(name)[arraySort(x -> -x[x], groupArray(score))[1]] AS top_names, groupArray(score)[arraySort(x -> -x[x], groupArray(score))[1]] AS top_scores FROM student_score GROUP BY course ); ``` 在这个例子中,我们首先通过 `groupArray()` 将同一课程下的所有学生姓名和分数收集到数中,再利用 `arraySort()` 对这些数进行排序,最后提出每的第一个元素作为结果。这种方式虽然稍显复杂,但在某些特定情况下可能更加灵活[^1]。 --- #### 方法三:窗口函数模拟 尽管 ClickHouse 不完全支持标准的 SQL 窗口函数语法,但我们仍然能够模仿其行为以达到相同的效果。例如: ```sql SELECT * FROM ( SELECT *, rowNumberInGroup() OVER (PARTITION BY user_id ORDER BY gmt_create DESC) AS rn FROM app_device_info WHERE gmt_create >= '2023-11-24 00:00:00' AND gmt_create <= '2023-11-25 00:00:00' ) WHERE rn = 1; ``` 这里的关键在于定义了一个虚拟列 `rn`,它表示当前记录在其所属分组内的排名位置。最终只筛选出那些满足条件 (`rn = 1`)记录即可[^3]。 --- ### 总结 以上三种方式各有优劣: - **方法一** 是最推荐的选择,因为它不仅易于理解和编写,而且性能表现良好; - **方法二** 更适合于需要进一步加工或扩展的情况; - 而 **方法三** 则提供了一种接近传统关系型数据库风格的操作手段。 无论采用哪种方案,请务必根据实际业务需求以及底层数据结构特点做出合理决策。
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值