【问题标题】:what is wrong with this MYSQL query? Amazon Interview question这个 MYSQL 查询有什么问题?亚马逊面试题
【发布时间】:2021-12-31 09:49:06
【问题描述】:

提示问题
编写一个查询来识别返回的活跃用户。返回活跃用户是指在任何其他购买后的 7 天内进行了第二次购买的用户。输出这些返回活跃用户的 user_id 列表。

CREATE TABLE amazon_transactions(
    id         int,
    user_id    int,
    itemvar    char,
    created_at datetime,
    revenue    int
)

我的解决方案如下。我得到了一个部分正确的答案。有许多不应该存在的用户 ID。 谁能告诉我我的解决方案出了什么问题?

select
    user_id
from
    amazon_transactions t1
where
    7 < ANY(
        select
            ABS( DATEDIFF( t1.created_at, t2.created_at ) ) 
        from
            amazon_transactions t2 
        where
            t2.user_id = t1.user_id
    );

【问题讨论】:

  • 请使用您的查询和示例数据将 linq 发布到 DbFiddle 或 SqlFiddle。
  • 看起来完全错误。你为什么使用8 &lt;?这肯定会找到时间间隔为至少 8 天的用户吗?不是“7 以内”。您还需要考虑不要将交易与自身进行比较。并考虑性能。窗口函数可以更高效吗?
  • 感谢您指出。 8 是一个错字。我正在使用 7 运行查询
  • 开发人员对自己的代码存在盲点。我们一直在为此奋斗。尝试创建一个小测试用例来测试您的查询。尽量避免提出可以通过“只看结果”来回答的问题。我们有时无法让自己简单地观察行为,因为“我们只知道它是正确的,而不是观察”
  • @MartinSmith MySql 文档dev.mysql.com/doc/refman/8.0/en/any-in-some-subqueries.html 说它评估为TRUEFALSEUNKNOWN

标签: mysql sql


【解决方案1】:

这是解决问题的方法

select DISTINCT user_id
  from amazon_transaction a
where exists (select null
                from amazon_transaction b
               where a.user_id=b.user_id
                 and a.id <> b.id 
                 and abs(datediff(b.created_at,a.created_at))<=7
                 )

【讨论】:

  • a.id b.id 消除了比较同一事务的可能性。
  • 是的,如果 id 是 transaction_id 并且是唯一的,那将是理想的方式
  • 谢谢它的工作。需要用 ABS() 括起来 dateiff
  • 我不明白你为什么需要 ABS(),它是多余的
  • @MartinSmith 是的,领先/落后也是我的选择。如果mysql的版本支持的话。
【解决方案2】:

使用

select
    t1.user_id
from
    amazon_transactions t1
join amazon_transactions t2
on t1.user_id = t2.user_id and ABS(DATEDIFF(t1.created_at, t2.created_at )) <= 7 and t1.id <> t2.id

或者

select
    user_id
from
    amazon_transactions t1
where
    7 >= ANY(
        select
            ABS( DATEDIFF( t1.created_at, t2.created_at ) ) 
        from
            amazon_transactions t2 
        where
            t2.user_id = t1.user_id
    );

【讨论】:

  • 每个user_idcreated_at 不为空的交易都会遇到这个问题,因为没有什么可以阻止交易匹配自己
  • 条件t1.created_at t2.created_at 可以添加到join条件中
  • 为什么不直接使用id 字段呢? (虽然我猜 Q 并不完全清楚如果同时购买以某种方式存在应该如何处理)顺便说一下不是我的 DV
  • 可以,id也可以用。
【解决方案3】:
SELECT DISTINCT user_id
FROM amazon_transaction t1
WHERE EXISTS ( SELECT NULL
               FROM amazon_transaction t2
               WHERE t1.id < t2.id
                 AND t1.user_id = t2.user_id
                 AND t2.created_at < t1.created_at + INTERVAL 7 DAY )

任务有点模棱两可。也许你必须调整查询——例如,使用t1.id &lt;&gt; t2.idt2.created_at &lt;= t1.created_atINTERVAL 6 DAY...

【讨论】:

    猜你喜欢
    • 2011-08-30
    • 2011-07-18
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多