簡體   English   中英

SQL查詢以查找分組值的所有組合

[英]SQL query to find all combinations of grouped values

我正在尋找一個SQL查詢或一系列SQL查詢。

架構

  • 我有一個包含三列的日志記錄表: idevent_typetimestamp
  • ID是任意文本,在運行時隨機生成,對我來說是未知的
  • 事件類型是已知事件類型的有限集合中的數字
  • 時間戳是您典型的int64紀元時間戳
  • 一個ID值可能包含1或更多行,每行都有一些event_type值。 代表與相同ID相關的事件流
  • 對於每個ID,可以通過增加時間戳來對其行集合進行排序
  • 在大多數情況下,ID +事件類型組合只會出現一次,但很少會出現兩次。 不確定這很重要

目標

我想做的是查詢事件類型的不同組合數(按時間戳排序)。 例如,提供此表:

id          event_type          timestamp
-----------------------------------------
foo         event_1             101
foo         event_2             102
bar         event_2             102
bar         event_1             101
foo         event_3             103
bar         event_3             103
blah        event_1             101
bleh        event_2             102
backwards   event_1             103
backwards   event_2             102
backwards   event_3             101

然后我應該得到以下結果:

combination               count
-------------------------------
[event_1,event_2,event_3]   2    // foo and bar
[event_3,event_2,event_1]   1    // backwards
[event_1]                   1    // blah
[event_2]                   1    // bleh

您可以對數據進行2級分組。
對於Mysql使用group_concat()

select t.combination, count(*) count
from (
  select
    group_concat(event_type order by timestamp) combination
  from tablename
  group by id
) t
group by t.combination
order by count desc

參見演示
對於Postgresql,請使用array_agg()array_to_string()

select t.combination, count(*) count
from (
  select
    array_to_string(array_agg(event_type order by timestamp), ',') combination
  from tablename
  group by id
) t
group by t.combination
order by count desc

參見演示
對於Oracle,listagg()

select t.combination, count(*) count
from (
  select
    listagg(event_type, ',') within group (order by timestamp) combination
  from tablename
  group by id
) t
group by t.combination
order by count desc

參見演示
對於SQL Server 2017+,有string_agg()

select t.combination, count(*) count
from (
  select
    string_agg(event_type, ',') within group (order by timestamp) combination
  from tablename
  group by id
) t
group by t.combination
order by count desc

參見演示
結果:

| combination             | count |
| ----------------------- | ----- |
| event_1,event_2,event_3 | 2     |
| event_3,event_2,event_1 | 1     |
| event_1                 | 1     |
| event_2                 | 1     |
SELECT
    "combi"."combination",
    COUNT(*) AS "count"
FROM 
    (
        SELECT
            GROUP_CONCAT("event_type" SEPARATOR ',') AS "combination"
        FROM
            ?table?
        GROUP BY
            "id"
    ) AS "combi"
GROUP BY
  "combi"."combination"

注意: GROUP_CONCAT(... SEPARATOR ...)語法不是SQL標准,而是特定於數據庫的(在這種情況下,MySQL,其他數據庫具有其他聚合函數)。 您可能需要根據選擇的數據庫進行調整,或者在標簽中指定實際使用的數據庫。

至於“按時間戳排序”,則需要定義其實際含義。 一組組的“按時間戳排序”是什么?

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM