位置| hackerrank | MSSQL
#教程 #database #mssql #hackerrank

问题

在这个SQL问题中,我们给了三张表:学生,朋友和包裹。

学生表包含两个列:

  • ID(学生的ID)和
  • 名称(学生的名字)。

朋友表包含两个列:

  • ID(学生的ID)和
  • friend_id(学生唯一最好的朋友的ID)。

包装表包含两个列:

  • ID(学生的ID)和
  • 薪水(以每月$ $为$的薪水提供给学生的薪水)。

这是这三个表的视觉表示:

all the 3 tables

任务是编写一个SQL查询,该查询输出那些最好的朋友提供的薪水比他们更高的学生的名字。名称应按照提供给最好的朋友的薪水订购。还可以保证,没有两个学生获得相同的薪水。

解释

考虑以下输入:

students sample input

friends and packages sample input

预期的输出应为:

Samantha
Julia
Scarlet

这是原因:

table contain name, salary, friend id and friend salary

萨曼莎(Samantha),朱莉娅(Julia)和斯嘉丽(Scarlet)最好的朋友都得到了比他们更高的薪水,而阿什利(Ashley)最好的朋友却没有。

解决方案

在这里,我提出了两种使用略有不同方法的SQL解决方案。每个人都有自己的优势,劣势和适用性。

直接加入方法

第一个源代码使用直接加入操作来链接所有表的必要数据:

SELECT s.name
FROM Students s JOIN Friends f ON s.ID = f.ID
JOIN Packages p1 ON p1.ID = s.ID
JOIN Packages p2 ON p2.ID = f.Friend_ID
WHERE p1.Salary < p2.Salary
ORDER BY p2.Salary

在这种方法中,我们直接根据各​​自的IDS加入学生,朋友和包装表。加入桌子后,我们滤除了(来自p1)薪水的学生(来自p2的薪水),最终由朋友的薪水订购结果。这是一种直接且易于理解的方法。

子查询加入方法

第二个解决方案在加入之前使用子查询来预滤伍:

SELECT s1.Name
FROM 
    (
        SELECT s.ID, s.Name, p.Salary
        FROM Students s
        JOIN Packages p ON s.ID = p.ID
    ) s1
JOIN 
    (
        SELECT f.ID, p.Salary [Friend_Salary]
        FROM Friends f
        JOIN Packages p ON f.Friend_ID = p.ID
    ) s2 ON s1.ID = s2.ID
WHERE s1.Salary < s2.Friend_Salary
ORDER BY s2.Friend_Salary

在这里,我们没有立即加入所有表,而是创建了两个子Queries s1s2,以预先加入学生和包装桌,以及朋友和包装表。然后,我们加入ID上的这两个子查询结果,过滤学生的薪水小于朋友的薪水,并由朋友的薪水订购结果。如果表之间存在显着尺寸差异,则这种方法可以更有效,因为它会在联接操作之前降低数据的大小。

结论

两种方法都在解决此问题方面有效,其差异主要在于其性能和可伸缩性,而桌子尺寸不同。根据实际的数据分布和大小,由于加入过程中的数据大小降低,子查找方法可能会提供更好的性能。

您可以在HackerRank中找到原始问题。

有关更有见地的解决方案和与技术相关的内容,请随时在我的Beacons page上与我联系。

👉 all the links on my beacons.ai page 👈