如何加入一个表两次

Posted

技术标签:

【中文标题】如何加入一个表两次【英文标题】:How to join a table twice 【发布时间】:2019-01-20 10:26:01 【问题描述】:

我有以下两张表,我想加入他们做第三张表

表 A

customer_id first_order_date last_order_date
123          2017-04-06        2018-07-30
456          2017-08-07        2018-07-24
789          2018-03-13        2018-07-03

表 B

order_id customer_id order_created_at num_of_products num_of_x_products
abc       123         2017-04-06           4              2
xyz       123         2018-07-30           5              3
def       456         2017-08-07           6              6
lmn       456         2018-07-24           4              1
ghi       789         2018-03-13           6              5
pqr       789         2018-07-03           3              3

我想加入这两个表并创建第三个看起来像的表。我该怎么做?

customer_id first_order_date last_order_date first_num_of_products last_num_of_products
123           2017-04-06        2018-07-30        4         5
456           2017-08-07        2018-07-24        6         4

这是我的代码

 SELECT
          "cus".customer_id
          ,"fo".order_created_at as first_order_created_at
          ,"fo".order_id as first_order_id
          ,"fo".number_of_products as first_number_of_products   
          ,"lo".order_created_at as last_order_created_at
          ,"lo".order_id as last_order_id
          ,"lo".number_of_products as last_number_of_products

        FROM table_a AS "cus"
        INNER JOIN table_b AS "fo" 
        ON "cus".customer_id = "fo".customer_id
        AND "cus".first_order_date = "fo".order_created_at
        INNER JOIN table_b AS "lo" 
        ON "cus".customer_id = "lo".customer_id
        AND "cus".last_order_date = "lo".order_created_at

【问题讨论】:

你研究过连接并尝试写一个吗? @dfundako 我有,似乎我必须将第一张桌子加入第二张桌子两次,但由于某种原因我没有得到任何结果。希望得到一些帮助! 分享你写的代码。 从你的样本数据和期望来看,我认为你不需要使用JOIN你只能写一个查询。 @dfundako 问题已包含在代码中 【参考方案1】:

从您的示例数据和预期结果来看,我认为您不需要使用JOIN,您只能编写这样的查询。

虽然这个例子是SQL-server,但snowflake支持row_number函数和窗口函数

JOINt1.order_created_at = t2.first_order_datet1.order_created_at = t2.last_order_datet1.customer_id = t2.customer_id 的子查询中的表A 和表B

结果只会得到first_order_datelast_order_date 所以使用Row_number 将行号设为order_created_at

    rn=1 意思是 first_order_date rn=2 意思是 last_order_date

使用条件聚合函数

CREATE TABLE TableA(
  customer_id INT,
  first_order_date DATE,
  last_order_date DATE
);


insert into TableA values (123,'2017-04-06','2018-07-30');
insert into TableA values (456,'2017-08-07','2018-07-24');
insert into TableA values (789,'2018-03-13','2018-07-03');


CREATE TABLE TableB(
  customer_id INT,
  order_created_at DATE,
  num_of_products INT,
  num_of_x_products INT
);


INSERT INTO TableB VALUES ( 123,'2017-04-06',4,2);
INSERT INTO TableB VALUES ( 123,'2018-07-28',15,13);
INSERT INTO TableB VALUES ( 123,'2018-07-30',5,3);
INSERT INTO TableB VALUES ( 456,'2017-08-07',6,6);
INSERT INTO TableB VALUES ( 456,'2018-07-24',4,1);
INSERT INTO TableB VALUES ( 789,'2018-03-13',6,5);
INSERT INTO TableB VALUES ( 789,'2018-07-03',3,3);

查询 1

SELECT customer_id,
       MIN(order_created_at) first_order_date,
       MAX(order_created_at) last_order_date, 
       MAX(CASE WHEN rn = 1 THEN num_of_products END) first_num_of_products,
       MAX(CASE WHEN rn = 2 THEN num_of_products END) last_num_of_products
FROM 
(
  select t1.*,ROW_NUMBER() OVER(PARTITION BY t1.customer_id ORDER BY t1.order_created_at) rn
  from TableB t1 
  INNER JOIN TableA t2 ON 
  (t1.customer_id = t2.customer_id) AND
  (t1.order_created_at = t2.first_order_date OR t1.order_created_at = t2.last_order_date)

) t1
WHERE t1.customer_id in (123,456)
GROUP BY t1.customer_id

Results

| customer_id | first_order_date | last_order_date | first_num_of_products | last_num_of_products |
|-------------|------------------|-----------------|-----------------------|----------------------|
|         123 |       2017-04-06 |      2018-07-30 |                     4 |                    5 |
|         456 |       2017-08-07 |      2018-07-24 |                     6 |                    4 |

【讨论】:

感谢您的回答,但大多数客户都有两个以上的订单。那只是一个例子。我很确定我将不得不使用连接 @PreetRajdeo 根据您的评论,我编辑了我的答案,您可以尝试将子查询写入JOINfirst_order_date last_order_date,如果rn=1 则首先rn=2 表示最后。

以上是关于如何加入一个表两次的主要内容,如果未能解决你的问题,请参考以下文章

有条件加入同一张表两次

mysql加入2个表 - 但必须加入同一个表两次

Laravel Eloquent Eager Loading:加入同一张表两次

加入表两次 - 在同一个表的两个不同列上

在 2 个数据帧 Spark 中缓存同一张表两次

加入同一个表时 SQL 结果计数发生变化