需要解决方案以避免重复扫描巨大 table

Need solution to avoid repeated scanning in huge table

我有一个事件 table,它有 40 列并填充多达 20 亿条记录。在那种情况下 table 我想查询组合事件,即事件 A 与事件 B。有时我可能想找到更多组合,例如事件 A 与 B 和 C。它可能会达到 5 或 6 组合。

我不想扫描 table 每个组合事件,即扫描事件 A 和扫描事件 B。我还需要一种通用方法来进行更多组合扫描。

注意:这 20 亿条记录是根据事件日期进行分区的,数据是平均分配的。

例如:

需要找到具有事件 A、B、C 的 ID,并且需要找到只有 A、B 的 ID。

这个数字组合是动态的。我不想为每个事件扫描 table 并最终与结果相交。

SELECT * from table as A
JOIN table AS B
    ON A.Id = B.Id AND A.Date = B.Date
WHERE Date = '1-Jan'
AND A.Event = 'A'
AND B.Event = 'B'

这将为您提供行,其中日期为“1 月 1 日”,两个事件的 ID 相同。 如果您想按更多事件进行过滤,可以一次又一次地加入 table。

having clause allows you to filter using the result of an aggregate function。我使用的是常规计数,但您可能需要不同的计数,具体取决于您的 table 设计。

示例:

-- Returns ids with 3 or more events.
SELECT
    x.Id,
    COUNT(*) AS EventCount
FROM
(
    VALUES
        (1, '2017-01-01', 'A'),
        (1, '2017-01-01', 'B'),
        (1, '2017-01-03', 'C'),
        (1, '2017-01-04', 'C'),
        (1, '2017-01-05', 'E'),
        (2, '2017-01-01', 'A'),
        (2, '2017-01-01', 'B'),
        (3, '2017-01-01', 'A')
) AS x(Id, [Date], [Event])
GROUP BY
    x.Id
HAVING 
    COUNT(*) > 2
;

Returns

Id  EventCount
1   5

使用相当于 mysql group_concat 功能的 sql 服务器可能会有一些好处。 例如

drop table t
create table t (id int, dt date, event varchar(1))
insert into t values
(1,'2017-01-01','a'),(1,'2017-01-01','b'),(1,'2017-01-01','c'),(1,'2017-01-02','c'),(1,'2017-01-03','d'),
(2,'2017-02-01','a'),(2,'2017-02-01','b')

select id,
        stuff(
    (
    select cast(',' as varchar(max)) + t1.event
    from t as t1
    WHERE t1.id  = t.id
    order by t1.id
    for xml path('')
    ), 1, 1, '') AS groupconcat
from t
group by t.id

Results in

id          groupconcat
----------- -----------
1           a,b,c,c,d
2           a,b

如果你再添加一个patindex

select * from
(
select id,
        stuff(
    (
    select cast(',' as varchar(max)) + t1.event
    from t as t1
    WHERE t1.id  = t.id
    order by t1.id
    for xml path('')
    ), 1, 1, '') AS groupconcat
from t
group by t.id
) s
where patindex('a,b,c%',groupconcat) > 0 

你明白了

id          groupconcat
----------- ------------
1           a,b,c,c,d