暂无图片
暂无图片
暂无图片
暂无图片
暂无图片

SQL进阶技巧:如何利用SQL巧解公务员逻辑推理题?

会飞的一十六 2024-12-26
85

点击上方【蓝色】字体   关注我们



01 场景描述 

逻辑测试题
A、B两男士好奇问C女士年龄
C 女士给出 11个可能答案:
35、36、38.
42、45、46.
51、55、57、
61、62.
C将十位数告诉 A,将个位数告诉 B。
A 说:我不知道℃女士年龄,B也不知道。
B 说:原本我不知道的,但现在知道了!
A 说:现在我也知道了!
请问C女士年龄是多少?
逻辑推理过程
第一步:分析 A 说的第一句话
A 说 “我不知道 C 女士年龄,B 也不知道”。
A 只知道年龄的十位数,他能确定 B 仅通过个位数无法得知年龄,这意味着这个十位数对应的所有个位数情况都不是唯一出现的。如果某个十位数对应的个位数是唯一的,比如十位数是 3 ,个位数是 8 ,若 B 被告知个位数是 8 ,他就能马上确定年龄是 38 岁了,但 A 确定 B 不知道,所以可以排除个位数唯一的情况。
观察所给的年龄,个位数 5、6、1、2 都分别在多个年龄中出现,而 38、42 中的 8 和 2 是唯一出现的,所以要排除十位数是 3 和 4 开头的年龄,此时剩下的年龄为:51、55、57、61、62。
第二步:分析 B 说的话
B 说 “原本我不知道的,但现在知道了”。
B 通过 A 的话能推理出第一步排除后的年龄范围(51、55、57、61、62),然后 B 能确定年龄了,这说明在剩下的这些年龄中,B 所知道的个位数是唯一能确定的,那就不会是 1 了(因为有 51 和 61 ),所以此时剩下的年龄为:55、57、62。
第三步:分析 A 说的第二句话
A 说 “现在我也知道了”。
A 只知道十位数,在剩下的 55、57、62 这几个年龄中,如果十位数是 5 ,A 依然无法确定是 55 还是 57 ,而现在 A 能确定了,所以只能是十位数为 6 的情况,即 C 女士的年龄是 62 岁。
综上,通过逐步推理分析 A、B 两人的话语,可以得出 C 女士的年龄是 62 岁。
需求:采用SQL语言模拟上述过程。


 02 数据准备 

    CREATE TEMPORARY TABLE ages (
        tens INT,  -- 十位数字
        ones INT  -- 个位数字
    );


    INSERT INTO ages VALUES
    (3, 5),
    (3, 6),
    (3, 8),
    (4, 2),
    (4, 5),
    (4, 6),
    (5, 1),
    (5, 5),
    (5, 7),
    (6, 1),
    (6, 2);


    03 问题分析 

    步骤1:模拟 A 说的第一句话进行筛选(排除十位数对应的个位数有唯一值的情况)
      -- 第一步筛选,找出个位数字不唯一对应的十位数,排除34开头的
      SELECT DISTINCT tens, ones
      FROM ages
      WHERE tens NOT IN (
          SELECT tens
          FROM (
              SELECT tens, COUNT(DISTINCT ones) AS unique_count
              FROM ages
              GROUP BY tens
          ) AS subquery
          WHERE unique_count = 1
      );
      首先在子查询中,通过 GROUP BY tens 按照十位数进行分组,然后使用 COUNT(DISTINCT ones) 统计每个十位数对应的不同个位数的数量,也就是看每个十位数下个位数字是否唯一。如果 unique_count = 1,说明这个十位数对应的个位数字是唯一出现的,比如十位数是 3 时对应个位数字 8 是唯一的,不符合条件,要把这样的十位数排除掉。外层查询再选取不在这些要排除的十位数中的数据行,经过这一步筛选后剩下的数据如下
      tens
      ones
      5
      1
      5
      5
      5
      7
      6
      1
      6
      2
      步骤2:模拟 B 说的话进行第二次筛选(在第一步结果基础上,排除个位数字重复的情况)
        -- 第二步筛选,在第一步结果基础上,排除个位数字重复的情况
        SELECT DISTINCT tens, ones
        FROM (
            SELECT *,
                   COUNT(*) OVER (PARTITION BY ones) AS count_per_ones
            FROM (
                SELECT DISTINCT tens, ones
                FROM ages
                WHERE tens NOT IN (
                    SELECT tens
                    FROM (
                        SELECT tens, COUNT(DISTINCT ones) AS unique_count
                        FROM ages
                        GROUP BY tens
                    ) AS subquery
                    WHERE unique_count = 1
                )
            ) AS subquery_1
        ) AS subquery_2
        WHERE count_per_ones = 1;
        先在最内层子查询中复用第一步筛选的逻辑,得到第一步筛选后的结果集。然后在中间的子查询里,使用分析函数 COUNT(*) OVER (PARTITION BY ones) 按照个位数字进行分区统计出现的次数,也就是看每个个位数字在当前剩下的数据里出现了几次。外层查询再选取那些 count_per_ones = 1 的数据行,即个位数字唯一能确定的情况,经过这一步筛选后剩下的数据如下:
          tens	ones
          5 7
          6 2
          步骤3:模拟 A 说的第二句话进行最终筛选(在第二步结果基础上,排除十位数重复的情况) 
            -- 第三步筛选,在第二步结果基础上,排除十位数重复的情况
            SELECT tens, ones
            FROM (
                SELECT *,
                       COUNT(*) OVER (PARTITION BY tens) AS count_per_tens
                FROM (
                    SELECT DISTINCT tens, ones
                    FROM (
                        SELECT *,
                               COUNT(*) OVER (PARTITION BY ones) AS count_per_ones
                        FROM (
                            SELECT DISTINCT tens, ones
                            FROM ages
                            WHERE tens NOT IN (
                                SELECT tens
                                FROM (
                                    SELECT tens, COUNT(DISTINCT ones) AS unique_count
                                    FROM ages
                                    GROUP BY tens
                                ) AS subquery
                                WHERE unique_count = 1
                            )
                        ) AS subquery_1
                    ) AS subquery_2
                    WHERE count_per_ones = 1
                ) AS subquery_3
            ) AS subquery_4
            WHERE count_per_tens = 1;
            同样是从内向外看,先复用前面两步的子查询逻辑得到第二步筛选后的结果集,接着在中间的子查询里,使用分析函数 COUNT(*) OVER (PARTITION BY tens) 按照十位数进行分区统计出现的次数,也就是看每个十位数在当前剩下的数据里出现了几次。最外层查询选取 count_per_tens = 1 的数据行,意味着通过十位数能唯一确定的情况,最终得到的结果如下:
              tens	ones
              6 2
              这就表示 C 女士的年龄是 62 岁,通过 SQL 代码逐步模拟了题目中 A、B 两人的推理过程,从而得出了最终答案。请注意,实际应用中可以根据具体数据库对临时表、语法等进行适当调整优化,这里主要侧重于展示逻辑推理在 SQL 中的实现方式。

               04  小 结      

              解题关键思路
              把握信息传递特点:这类问题中,不同角色掌握着年龄数字不同位置(十位、个位等)的信息,要通过他们各自宣称 “知道” 或 “不知道” 的话语来推断出隐藏的年龄,关键在于分析每个角色依据所掌握信息以及对方话语能做出怎样的合理推断。
              逐步排除法为主:通常是根据第一个角色的陈述先排除掉一些明显不符合条件的数字组合,然后再依据后续角色的话语进一步缩小范围,通过层层筛选,最终确定唯一符合所有条件的年龄数值。
              常见推理依据
              唯一性判断:比如在最初被告知部分信息时,如果某个已知数位所对应的另一位数是唯一的,那么一旦有人能确定知道年龄,就说明这个唯一对应的情况存在;反之,如果说不知道,那就要排除那些会造成唯一对应情况的数字组合。像 A 说不知道且确定 B 也不知道,往往就是排除那些十位数字对应的个位数字有唯一性的情况,因为若存在这种唯一性,B 就有可能直接知晓年龄了。
              剩余选项的唯一性再判断:当经过第一步排除后,后续角色能确定年龄了,这意味着在剩下的数字组合中,其所知的数位信息在当前剩余情况里是唯一能确定具体年龄的,所以要再次依据这个唯一性去排除有重复该数位的其他数字组合。例如 B 说知道了,那就可以排除剩余选项里个位数字重复的情况。
               SQL 解题拓展思路(如何用 SQL 来解决这类问题)
              数据构建与模拟:首先要将题目中的年龄可能值通过创建表或者临时表等方式在数据库中表示出来,把年龄拆分成对应的数位(十位和个位等)存储为不同字段,以此来模拟题目中人物所掌握的信息情况。
              分层筛选逻辑:按照题目中不同角色的推理顺序,通过 SQL 语句分层进行筛选。第一层一般是根据第一个角色话语所蕴含的逻辑,利用条件筛选(如 WHERE 子句)、分组统计(结合 GROUP BY 与聚合函数)等操作排除不符合条件的记录;后续层则依据其他角色的话,继续运用分析函数、子查询等进一步缩小范围,每一层都以前面的结果为基础,不断精准定位到最终符合所有条件的年龄记录。
              对逻辑思维锻炼的意义
              强化逻辑分析能力:解决年龄推理问题需要严谨地梳理信息、分析条件之间的关联以及合理地推导结论,有助于提升从复杂表述中提取关键逻辑线索并进行有序思考的能力。
              培养多角度思考习惯:要站在不同角色所掌握的有限信息角度去推测整体情况,这促使解题者学会换位思考、从多个视角审视问题,进而更全面、灵活地应对各类逻辑挑战。
              总之,年龄推理问题是一种趣味性与逻辑性兼具的SQL题型,无论是通过纯逻辑推理还是借助 SQL 等工具去解决,都对锻炼思维、提升逻辑分析水平有着积极的作用。

              会飞的一十六

              微信号:ddan_hashcode

              扫描右侧二维码关注我们






              点个【在看】 你最好看






              往期精彩
              数势科技指标平台, 让数据产生最大价值
              数仓建模:什么是全量表,增量表,快照表,拉链表,流水?
              指标体系建设:如何理解指
              指标体系建设:如何进行自下而上的指标收集?
              指标体系构建:如何设计北极星指标设计?
              指标体系建设:如何进行自上而下的指标拆解?
              点击"阅读原文"按钮获取跟多~~

              文章转载自会飞的一十六,如果涉嫌侵权,请发送邮件至:contact@modb.pro进行举报,并提供相关证据,一经查实,墨天轮将立刻删除相关内容。

              评论