如何优化两个表的JOIN,这些表需要在列上进行查找才能加入?

时间:2016-02-01 19:01:29

标签: mysql inner-join cross-join

我正在对两个表进行简单的INNER JOIN,并且要求每个表必须首先与单独的1:n表连接才能获得正确的连接值。举一个简单的例子,我有三个表 UserInstalls (UserId,InstallDate), UserConversion (UserId,ConversionDate)和 UserAccounts (UserId,帐户ID)。我想要(AccountId,InstallDate,ConversionDate)的最终结果。

UserInstalls
+--------+-------------+
| UserId | InstallDate |
+--------+-------------+
|      1 | 2015-01-11  |
|      2 | 2015-03-21  |
|      3 | 2015-02-05  |
|      4 | 2014-06-01  |
|      5 | 2014-01-23  |
|      6 | 2015-02-14  |
+--------+-------------+
UserConversion
+--------+----------------+
| UserId | ConversionDate |
+--------+----------------+
|      7 | 2015-01-15     |
|      8 | 2015-03-03     |
|      9 | 2015-08-01     |
|     10 | 2015-01-02     |
|     11 | 2014-01-24     |
|     12 | 2015-02-17     |
+--------+----------------+
UserAccounts
+--------+-----------+
| UserId | AccountId |
+--------+-----------+
|      1 |         1 |
|      7 |         1 |
|      2 |         2 |
|      8 |         2 |
|      3 |         3 |
|      9 |         3 |
|      4 |         4 |
|     10 |         4 |
|      5 |         5 |
|     11 |         5 |
|      6 |         6 |
|     12 |         6 |
+--------+-----------+

我可以简单地使用子查询来查找AccountID,然后加入每个子查询的结果。在这个琐碎的案例中,这很好。在涉及(10,000多行)的实际应用中,这是无效的,我遇到了线轴限制。

SELECT x.AccountID, InstallDate, ConversionDate
FROM (SELECT AccountID, InstallDate FROM UserInstalls
    JOIN UserAccounts
    ON UserInstalls.UserId = UserAccounts.UserId) x
JOIN (SELECT AccountID, ConversionDate FROM UserConversion 
    JOIN  UserAccounts
    UserConversion.UserId = UserAccounts.UserId) y
ON x.AccountId = y.AccountId;

没有子查询或通过脚本创建多个表的任何想法吗?交叉连接?关系分裂?

谢谢!

3 个答案:

答案 0 :(得分:0)

您应该能够在没有子查询的情况下将表连接在一起:

SELECT ua1.AccountID, ui.InstallDate, uc.ConversionDate
FROM UserAccounts ua1
JOIN UserInstalls ui on ua1.UserId = ui.UserId
JOIN UserAccounts ua2 on ua1.AccountID = ua2.AccountID
JOIN UserConversion uc on uc.UserId = ua2.UserId

答案 1 :(得分:0)

您需要左连接,但从用户帐户表开始作为根...

select
      UA.AccountID, 
      MAX( UI.InstallDate ) as AccountInstalled,
      MAX( UC.ConversionDate ) as ConversionDate
   from
      UserAccounts UA
         LEFT JOIN UserInstalls UI
            on UA.UserID = UI.UserID
         LEFT JOIN UserConversion UC
            on UA.UserID = UC.UserID
   group by
      UA.AccountID

基于帐号的小组基本上会查看从任何一方获得加入资格的小组。您现在每人将拥有一行以及相应的安装和转换日期。

答案 2 :(得分:0)

请检查下面的查询,如果没有得到所需的结果,那么创建一个sqlfiddle,以便我可以检查问题。

SELECT ua1.AccountID, ui.InstallDate, uc.ConversionDate 
FROM UserInstalls  ui
JOIN UserAccounts ua ON ui.UserId=ua.UserId
JOIN UserConversion uc ON ui.UserId=uc.UserId 
JOIN UserAccounts ua1 ON ua.AccountId=ua1.AccountId;