频繁项集SQL

频繁项集SQL,sql,frequency,Sql,Frequency,我正在用SAS做一个课程作业。目前,我有一组订单ID和产品ID。我想知道哪些产品最常一起订购。想想,牛奶和谷类食品在食品篮子里 我不太擅长编程,所以如果有人能抽出一点时间编写几行简单的SQL语句,我会非常感激。它不是一个沉重的数据集,只有两列(订单ID和产品ID) 例如: 订单ID产品ID 1000164564564 10001546456 1000154646 100035464 10003342346 我现在花了三个小时研究,有点绝望:(像这样的东西怎么样: create table ord

我正在用SAS做一个课程作业。目前,我有一组订单ID和产品ID。我想知道哪些产品最常一起订购。想想,牛奶和谷类食品在食品篮子里

我不太擅长编程,所以如果有人能抽出一点时间编写几行简单的SQL语句,我会非常感激。它不是一个沉重的数据集,只有两列(订单ID和产品ID)

例如:

订单ID产品ID

1000164564564

10001546456

1000154646

100035464

10003342346


我现在花了三个小时研究,有点绝望:(

像这样的东西怎么样:

create table order_together (order_id, product_id1, product_id2);

insert into order_together
(order_id, product_id1, product_id2)
select o1.order_id, o1.product_id, o2.product_id
from order_line o1, order_line o2
where o1.order_id = o2.order_id 

/* you dont want them equal and you also dont
want to insert cereal-milk and milk-cereal on the same order*/
and o1.product_id < o2.product_id
那就更好了

回应记者的评论

但您正在获取来自同一订单的订单行的不同行的成对订购产品

在sqlfiddle.com上试试这个

将其放在左侧的“构建架构”窗格中。它将创建表

create table order_line(order_no int, product_id varchar(10));

create table order_together(order_no int, product_id1 varchar(10), product_id2 varchar(10));
将其放在右侧窗格中,运行SQL

insert into order_line(order_no, product_id) values(1, 'milk');
insert into order_line(order_no, product_id) values (1, 'cereal');
insert into order_line(order_no, product_id) values (1, 'rice');
insert into order_line(order_no, product_id) values (2, 'milk');
insert into order_line(order_no, product_id) values (2, 'cereal');

insert into order_line(order_no, product_id) values (3, 'milk');
insert into order_line(order_no, product_id) values (3, 'cookies');
insert into order_line(order_no, product_id) values(4, 'milk');
insert into order_line(order_no, product_id) values (4, 'cookies');
insert into order_line(order_no, product_id) values(5, 'rice');
insert into order_line(order_no, product_id) values (5, 'icecream');

select o1.order_no, o1.product_id as product_from_row1, o2.product_id as product_from_row2
from order_line o1, order_line o2
where o1.order_no = o2.order_no
and o1.product_id < o2.product_id                            

试一试,然后考虑一下查询请求的内容,即连接相同顺序的不同订单行。这几乎就是“一起排序”的定义.

如果你仔细想想,你可以这样问问题来找到答案:对于每一对可能的产品,这两种产品以相同的顺序出现了多少次。然后按计数排序,将答案浮到顶部:

select 
    p1.product_id, p2.product_id, count(*) times_order_together 
from
    orders p1
    inner join
    orders p2
    on
        p1.order_id = p2.order_id
        and
        p1.product_id != p2.product_id 
group by
    p1.product_id, p2.product_id
order by
    count(*) desc 
从来没有一起订购过的产品根本不会出现。此外,成对表示两次,一行表示鸡蛋加牛奶,一行表示牛奶加鸡蛋。这些重复的成对表示是可拆卸的,但会变得更难看,简单就是好


更详细地说,
p1
p2
是订单的别名。这样做是为了能够多次使用数据源,并且能够区分它们。此外,
count(*)times\u order\u together
只是给计算命名为“times\u order\u together”。
count(*)
。这是计算订单中产品配对的次数。

您使用的是哪种DBMS?Postgres?Oracle?@a_horse_和_no_name Hi我不确定什么是DBMS,但我正在使用基于proc sqlHey@jl peyret的SAS!感谢回复,但我不确定(订单id、产品id 1、产品id 2)行吗?我的数据分为两列,分别是订单id和产品id。例如,第一列是由所有订单id组成的,第二列是与订单id对应的所有产品id。我编辑了我的问题,试图说明这一点!谢谢!但是我不明白如何选择p1.product\U id,p2.product\U id,如果它只来自一列?抱歉,如果这是一个愚蠢的问题,诀窍是从表中选择两次并将两个选择连接在一起。您从来没有告诉我们表的名称-在我的示例中,我猜测/假设表名为“orders”。这种技术称为同一个表连接,在使用基于sql的系统时非常常见.
order_no    product_from_row1   product_from_row2
1   milk    rice
1   cereal  milk
1   cereal  rice
2   cereal  milk
3   cookies     milk
4   cookies     milk
5   icecream    rice
select 
    p1.product_id, p2.product_id, count(*) times_order_together 
from
    orders p1
    inner join
    orders p2
    on
        p1.order_id = p2.order_id
        and
        p1.product_id != p2.product_id 
group by
    p1.product_id, p2.product_id
order by
    count(*) desc