草庐IT

看看你离世界一流大厂有多远?3道Google最新SQL面试题 ⛵

ShowMeAI 2023-03-28 原文

? 作者:韩信子@ShowMeAI
? 数据分析◉技能提升系列https://www.showmeai.tech/tutorials/33
? AI 面试题库系列https://www.showmeai.tech/tutorials/48
? 本文地址https://www.showmeai.tech/article-detail/297
? 声明:版权所有,转载请联系平台与作者并注明出处
? 收藏ShowMeAI查看更多精彩内容

下面是最新的 3 道 Google SQL 面试题和参考答案。这些题目面向的 Google 职位包括:数据科学 数据分析师商业智能 工程师数据工程师商业分析师

ShowMeAI 制作了快捷即查即用的 SQL 速查表手册,大家可以在下述位置获得:

? 面试题 1:墨西哥和美国第三高峰

问题: 请完成1个 SQL 来找出每个国家第三高的山名,并按 ASC 顺序对国家/地区排序。

Table: mountains
+---------------------+------+-------------+
|name                 |height|country      |
+---------------------+------+-------------+
|Denalli              |20310 |United States|
|Saint Elias          |18008 |United States|
|Foraker              |17402 |United States|
|Pico de Orizab       |18491 |Mexico       |
|Popocatépetl         |17820 |Mexico       |
|Iztaccihuatl         |17160 |Mexico       |
+---------------------+------+-------------+

参考答案:

SELECT "country",
       "name"
FROM   (SELECT "country",
               "name",
               Rank()
                 OVER (
                   partition BY "country"
                   ORDER BY "height" DESC) AS "rank"
        FROM   mountains) AS m
WHERE  "rank" = 3
ORDER  BY country ASC 

? 面试题 2:用 latest_event 查找当前打开的页数

问题: 给定下表,表中包含有关页面状态更改时间的信息。完成 SQL 查找当前使用 latest_event 的页面数。 注意,表中 page_flag 列将用于识别页面是『OFF』还是『ON』。

Table: pages_info
+-------+--------------------------------------+----------+
|page_id|event_time                            |page_flag |
+-------+--------------------------------------+----------+
|1      |current_timestamp - interval '6 hours'|ON        |
|1      |current_timestamp - interval '3 hours'|OFF       |
|1      |current_timestamp - interval '1 hours'|ON        |
|2      |current_timestamp - interval '3 hours'|ON        |
|2      |current_timestamp - interval '1 hours'|OFF       |
|3      |current_timestamp                     |ON        |
+-------+--------------------------------------+----------+

参考答案:

-- 首先,对于每个页面ID,让我们选择最新的记录(基于事件时间列)。
SELECT page_id,
       Max(event_time) AS latest_event
FROM   pages_info
GROUP  BY page_id 

-- 接着,我们将前面的查询与原表连接起来,并检查其中有多少人的标记页等于ON。
WITH latest_event
     AS (SELECT page_id,
                Max(event_time) AS latest_event
         FROM   pages_info
         GROUP  BY page_id)
SELECT Sum(CASE
             WHEN page_flag = 'ON' THEN 1
             ELSE 0
           END) AS result
FROM   pages_info pi
       JOIN latest_event le
         ON pi.page_id = le.page_id
            AND pi.event_time = le.latest_event; 

? 面试题 3:回访用户

问题: 在如下的数据库表中,包含有关用户访问网页的信息。 完成 SQL 返回连续访问该页面最长的 3 个用户,按长短的倒序排列 3 个用户。

Table: visits
+--------+----------------------------+
|user_id |date                        | 
+--------+----------------------------+
|1       |current_timestamp::DATE - 0 |
|1       |current_timestamp::DATE - 1 |
|1       |current_timestamp::DATE - 2 |
|1       |current_timestamp::DATE - 3 |
|1       |current_timestamp::DATE - 4 |
|2       |current_timestamp::DATE - 1 |
|4       |current_timestamp::DATE - 0 |
|4       |current_timestamp::DATE - 1 |
|4       |current_timestamp::DATE - 3 |
|4       |current_timestamp::DATE - 4 |
|4       |current_timestamp::DATE - 62|   
+--------+----------------------------+

参考答案:

--首先,让我们添加一个新的列,其值是每个用户的下一次访问(与当前日期不同)。我们将使用lead函数来完成:
SELECT DISTINCT user_id,
                date,
                Lead(date)
                  OVER (
                    partition BY user_id
                    ORDER BY date) AS next_date
FROM   (SELECT DISTINCT *
        FROM   visits) AS t; 
--接着,让我们创建另一个列,其目的是让我们知道访问的停止。这包括检查下一个日期是否与当前日期+1是否不同。
WITH next_dates
     AS (SELECT DISTINCT user_id,
                         date,
                         Lead(date)
                           OVER (
                             partition BY user_id
                             ORDER BY date) AS next_date
         FROM   (SELECT DISTINCT *
                 FROM   visits) AS t) --去重
SELECT user_id,
       date,
       next_date,
       CASE
         WHEN next_date IS NULL
               OR next_date = date + 1 THEN 1
         ELSE NULL
       END AS streak
FROM   next_dates; 
--接着,我们将为每个用户创建一个分区,每个分区代表一个连续的访问。从概念上讲,我们要做的是,对于每个用户,取最近的记录(基于日期)并赋值为0,然后寻找下面的记录,如果访问没有停止就赋值为0,如果访问停止就赋值为1(如果连胜列为空),然后继续这样做,直到每个连续访问被一个不同的分区所代表。执行这一逻辑的代码如下。
WITH next_dates
     AS (SELECT DISTINCT user_id,
                         date,
                         Lead(date)
                           OVER (
                             partition BY user_id
                             ORDER BY date) AS next_date
         FROM   (SELECT DISTINCT *
                 FROM   visits)),
     streaks
     AS (SELECT user_id,
                date,
                next_date,
                CASE
                  WHEN next_date IS NULL
                        OR next_date = date + 1 THEN 1
                  ELSE NULL
                END AS streak
         FROM   next_dates)
SELECT *,
       Sum(CASE
             WHEN streak IS NULL THEN 1
             ELSE 0
           END)
         OVER (
           partition BY user_id
           ORDER BY date) AS partition
FROM   streaks; 
--一旦我们有了这个分区,问题就容易了,现在我们只需要计算每个用户和分区的记录数,并找到计数最多的用户。完整的查询如下
WITH next_dates AS
(
                SELECT DISTINCT user_id,
                                date,
                                Lead(date) OVER (partition BY user_id ORDER BY date) AS next_date
                FROM            visits ), streaks AS
(
       SELECT user_id,
              date,
              next_date,
              CASE
                     WHEN next_date IS NULL
                     OR     next_date = date + 1 THEN 1
                     ELSE NULL
              END AS streak
       FROM   next_dates ), partitions AS
(
         SELECT   *,
                  Sum(
                  CASE
                           WHEN streak IS NULL THEN 1
                           ELSE 0
                  END ) OVER (partition BY user_id ORDER BY date) AS partition
         FROM     streaks ), count_partitions AS
(
         SELECT   user_id,
                  partition,
                  Count(1) AS streak_days
         FROM     partitions
         GROUP BY user_id,
                  partition )
SELECT   user_id,
         Max(streak_days) AS longest_streak
FROM     count_partitions
GROUP BY user_id
ORDER BY 2 DESC limit 3;

参考资料

有关看看你离世界一流大厂有多远?3道Google最新SQL面试题 ⛵的更多相关文章

  1. 报告回顾丨模型进化狂飙,DetectGPT能否识别最新模型生成结果? - 2

    导读语言模型给我们的生产生活带来了极大便利,但同时不少人也利用他们从事作弊工作。如何规避这些难辨真伪的文字所产生的负面影响也成为一大难题。在3月9日智源Live第33期活动「DetectGPT:判断文本是否为机器生成的工具」中,主讲人Eric为我们讲解了DetectGPT工作背后的思路——一种基于概率曲率检测的用于检测模型生成文本的工具,它可以帮助我们更好地分辨文章的来源和可信度,对保护信息真实、防止欺诈等方面具有重要意义。本次报告主要围绕其功能,实现和效果等展开。(文末点击“阅读原文”,查看活动回放。)Ericmitchell斯坦福大学计算机系四年级博士生,由ChelseaFinn和Chri

  2. Hive SQL 五大经典面试题 - 2

    目录第1题连续问题分析:解法:第2题分组问题分析:解法:第3题间隔连续问题分析:解法:第4题打折日期交叉问题分析:解法:第5题同时在线问题分析:解法:第1题连续问题如下数据为蚂蚁森林中用户领取的减少碳排放量iddtlowcarbon10012021-12-1212310022021-12-124510012021-12-134310012021-12-134510012021-12-132310022021-12-144510012021-12-1423010022021-12-154510012021-12-1523.......找出连续3天及以上减少碳排放量在100以上的用户分析:遇到这类

  3. sql - 查询忽略时间戳日期的时间范围 - 2

    我正在尝试查询我的Rails数据库(Postgres)中的购买表,我想查询时间范围。例如,我想知道在所有日期的下午2点到3点之间进行了多少次购买。此表中有一个created_at列,但我不知道如何在不搜索特定日期的情况下完成此操作。我试过:Purchases.where("created_atBETWEEN?and?",Time.now-1.hour,Time.now)但这最终只会搜索今天与那些时间的日期。 最佳答案 您需要使用PostgreSQL'sdate_part/extractfunction从created_at中提取小时

  4. sql - 在 Rails Console for PostgreSQL 的表中显示数据 - 2

    我找到了这样的东西:Rails:Howtolistdatabasetables/objectsusingtheRailsconsole?这一行没问题:ActiveRecord::Base.connection.tables并返回所有表但是ActiveRecord::Base.connection.table_structure("users")产生错误:ActiveRecord::Base.connection.table_structure("projects")我认为table_structure不是Postgres方法。如何列出Postgres数据库的Rails控制台中表中的所有

  5. ruby - Google-api-ruby-client 翻译 API 示例 - 2

    很高兴看到google代码:google-api-ruby-client项目,因为这对我来说意味着Ruby人员可以使用GoogleAPI-s来完善代码。虽然我现在很困惑,因为给出的唯一示例使用Buzz,并且根据我的实验,Google翻译(v2)api的行为必须与google-api-ruby-client中的Buzz完全不同。.我对“Explorer”演示示例很感兴趣——但据我所知,它并不是一个探索器。它所做的只是调用一个Buzz服务,然后浏览它已经知道的关于Buzz服务的事情。对我来说,Explorer应该让您“发现”所公开的服务和方法/功能,而不一定已经知道它们。我很想听听使用这个

  6. ruby - 防止SQL注入(inject)/好的Ruby方法 - 2

    Ruby中防止SQL注入(inject)的好方法是什么? 最佳答案 直接使用ruby?使用准备好的语句:require'mysql'db=Mysql.new('localhost','user','password','database')statement=db.prepare"SELECT*FROMtableWHEREfield=?"statement.execute'value'statement.fetchstatement.close 关于ruby-防止SQL注入(inject

  7. ruby-on-rails - 如何在 Rails 中的不同数据库上执行直接 SQL 代码 - 2

    我正在编写一个Rails应用程序,它将监视某些特定数据库的数据质量。为了做到这一点,我需要能够对这些数据库执行直接SQL查询——这当然与用于驱动Rails应用程序模型的数据库不同。简而言之,这意味着我无法使用通过ActiveRecord基础连接的技巧。我需要连接的数据库在设计时是未知的(即:我不能将它们的详细信息放在database.yaml中)。相反,我有一个模型“database_details”,用户将使用它来输入应用程序将在运行时执行查询的数据库的详细信息。因此与这些数据库的连接实际上是动态的,细节仅在运行时解析。 最佳答案

  8. 最新版人脸识别小程序 图片识别 生成二维码签到 地图上选点进行位置签到 计算签到距离 课程会议活动打卡日常考勤 上课签到打卡考勤口令签到 - 2

    技术选型1,前端小程序原生MINA框架cssJavaScriptWxml2,管理后台云开发Cms内容管理系统web网页3,数据后台小程序云开发云函数云开发数据库(基于MongoDB)云存储4,人脸识别算法基于百度智能云实现人脸识别一,用户端效果图预览老规矩我们先来看效果图,如果效果图符合你的需求,就继续往下看,如果不符合你的需求,可以跳过。1-1,登录注册页可以看到登录页有注册入口,注册页如下我们的注册,需要管理员审核,审核通过后才可以正常登录使用小程序1-2,个人中心页登录成功以后,我们会进入个人中心页我们在个人中心页可以注册人脸,因为我们做人脸识别签到,需要先注册人脸才可以进行人脸比对,进

  9. ruby - 如何从 URL 中删除 Google 跟踪参数 (UTM)? - 2

    我有一堆要清理的URL。它们都包含UTM参数,在这种情况下不是必需的,或者是有害的。示例:http://houseofbuttons.tumblr.com/post/22326009438?utm_source=feedburner&utm_medium=feed&utm_campaign=Feed%3A+HouseOfButtons+%28House+of+Buttons%29所有可能的参数都以utm_开头。如何使用ruby​​脚本/结构轻松删除它们而不破坏其他潜在的“好”URL参数? 最佳答案 您可以将正则表达式应用于url以清

  10. sql - Rails:使用 Postgres 创建对象时重复 ActiveRecord::RecordNotUnique? - 2

    我正在使用Rails4应用程序,它需要创建大量对象以响应来自另一个系统的事件。当我调用create!时,主键列上出现非常频繁的ActiveRecord::RecordNotUnique错误(由PG::UniqueViolation引起)我的模型之一。我在SO上找到了其他答案,建议挽救异常并调用retry:beginTableName.create!(data:'here')rescueActiveRecord::RecordNotUnique=>eife.message.include?'_pkey'#Onlyretryprimarykeyviolationslog.warn"Retr

随机推荐