MySQL多行子查询修复

时间:2016-11-15 21:34:20

标签: mysql

我试图在每个用户唯一的日期/时间之前返回所有用户的所有数据。

我可以返回每个用户的确切日期的所有数据,没问题,但我不知道如何扩展我的查询以返回小于或等于我的关键日期的日期。

我有一个2表SQL数据库。

表1 - “销售”有所有交易的确认记录。

  • user_id(日期,然后是各种购买信息)

表2 - “user_data”包含所有浏览数据的记录

  • user_id,record_date,purchase_made(purchase_made被错误命名,因为他们触发了购买弹出窗口,但可能没有实际购买 - 然后是一大堆用户操作数据)

我需要获取在购买之前和之后购买的用户的所有user_data记录。

为了获得确切的购买记录,我可以使用以下内容:

SELECT * 
FROM user_data 
WHERE user_id IN (SELECT user_id FROM sales) 
AND record_date IN (SELECT min(record_date) FROM user_data WHERE purchase_made = 1 GROUP BY user_id);

现在我真正想要的是能够将第二个“IN”更改为“< =”但是我不能使用返回超过1行的子查询来做到这一点。

免责声明 - 我没有写数据库,我没有权限更改数据库(也不是我这样做的合适人选)

免责声明2 - 我知道使用purchase_made会稍微破坏结果,因为并非所有这些都会被购买。但是由于报告的原因,销售表中的日期可能会超出足够的时间,因为它实际上比使用与purchase_made相关联的时间戳更可靠(通过对实际数据集运行的大量查询比较证明)。但是上面的任务是无关紧要,他们会对“大部分”准确感到高兴。

1 个答案:

答案 0 :(得分:0)

“现在我真正想要的是能够将第二个”IN“改为”< =“

因此,通过关联记录来使其成为相关子查询,我们消除了对“IN”的需求,现在可以使用<=

SELECT * 
FROM user_data UD
WHERE user_id IN (SELECT user_id FROM sales) 
  AND record_date <= (SELECT MIN(record_date) 
                      FROM user_data UD2 
                      WHERE UD2.purchase_made = 1 
                        AND UD2.User_ID = UD.User_ID);

另一种方法是将user_Id添加到子查询中,而不是子查询使其成为您基于user_ID加入的内联视图,然后根据连接条件比较日期。

SELECT * 
FROM 
    user_data UD
INNER JOIN 
   (SELECT MIN(record_date) mrd, User_ID 
    FROM user_data 
    WHERE purchase_made = 1
    GROUP BY User_ID) UD2 ON UD.user_Id = UD2.user_Id
                          AND UD.record_date <= UD2.RecordDate
WHERE 
    user_id IN (SELECT user_id FROM sales) 

我会考虑将where子句更改为...

WHERE 
    user_ID EXISTS (SELECT NULL FROM sales S WHERE S.user_ID = UD.user_ID)

我怀疑销售表会变得越来越大,而且随着时间的推移IN会降低性能,因为存在可以提前存在子查询,从而提高性能。