限制连接中每组的行数(不限制为 1 行)

2023-11-24

鉴于这些表:

TABLE Stores (
 store_id INT,
 store_name VARCHAR,
 etc
);

TABLE Employees (
 employee_id INT,
 store_id INT,
 employee_name VARCHAR,
 currently_employed BOOLEAN,
 etc
);

我想列出每家商店雇佣时间最长的 15 名员工(假设工作时间最低的 15 名员工)employee_id),或商店的所有员工(如果有 15 名员工)currently_employed='t'。我想用 join 子句来做到这一点。

我发现很多人这样做的例子only对于 1 行,通常是最小值或最大值(单个受雇时间最长的员工),但我基本上想将ORDER BY and a LIMIT连接内部。其中一些示例可以在这里找到:

  • 将连接表的结果限制为一行
  • MySQL 为每个产品返回 1 个图像

我还找到了逐家进行此操作的不错示例(我没有,我有大约 5000 家商店):

  • 获取每组分组结果的前n条记录

我还看到你可以使用TOP代替ORDER BY and LIMIT,但不适用于 PostgreSQL。

我认为两个表之间的连接子句并不是唯一的(甚至不一定是最好的方法),如果可以通过不同的方式工作的话store_id在员工表内部,所以我愿意接受其他方法。之后随时可以加入。

由于我对 SQL 非常陌生,因此我需要任何理论背景或其他解释来帮助我理解工作原理。


row_number()

获取每组前 n 行的一般解决方案是使用窗口函数row_number():

SELECT *
FROM  (
   SELECT *, row_number() OVER (PARTITION BY store_id ORDER BY employee_id) AS rn
   FROM   employees
   WHERE  currently_employed
   ) e
JOIN   stores s USING (store_id)
WHERE  rn <= 15
ORDER  BY store_id, e.rn;
  • PARTITION BY应该使用store_id,保证是唯一的(与store_name).

  • 首先识别行employees, then加入stores,这样更便宜。

  • To get 15 rows use row_number() not rank()(对于此目的来说,这是错误的工具)。 (尽管employee_id是唯一的,差异不显示。)

LATERAL

自 Postgres 以来的替代方案9.3与匹配的索引相结合通常会表现得更好,尤其从大表中检索小选择时。看:

  • LATERAL JOIN 和 PostgreSQL 中的子查询有什么区别?
SELECT s.store_name, e.*
FROM   stores s
CROSS  JOIN LATERAL (
   SELECT *  -- better just the needed columns!
   FROM   employees e
   WHERE  e.store_id = s.store_id
   AND    e.currently_employed
   ORDER  BY e.employee_id
   LIMIT  15
   ) e
-- WHERE ... work with selected stores?
ORDER  BY s.store_name, e.store_id, e.employee_id;

完美的索引将是部分多列索引,如下所示:

CREATE INDEX ON employees (store_id, employee_id) WHERE  currently_employed;

相关示例:

  • 使用空列创建唯一约束

这两个版本都排除了没有现有员工的商店。如果需要的话,有很多方法可以解决这个问题LEFT JOIN LATERAL ...

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

限制连接中每组的行数(不限制为 1 行) 的相关文章

  • 我可以从列 CHECK 约束调用用户定义的函数吗?

    我有一个返回 1 或 0 的用户定义的 SQL 函数 我想从列 CHECK 约束中调用它 是的 SQL Anywhere 没有布尔数据类型 因此您必须编写一个生成 TRUE FALSE 或 UNKNOWN 的谓词 换句话说 如果函数返回 1
  • 针对 SQL Server 的 SQL 查询的执行日期时间

    我曾经发现过这个很好的查询here https dba stackexchange com a 135080 43889 我想将查询的执行时间添加到以下查询中 USE master go SELECT sdest DatabaseName
  • mysql 中的 max(长度(字段))

    如果我说 select max length Name from my table 我得到的结果是 18 但我也想要相关数据 所以如果我说 select max length Name Name from my table 这是行不通的 我
  • 如何增加每次 INSERT INTO 迭代的值?

    我有一个查询 如下所示 第 1 列位于 另一列是 varchar 100 INSERT INTO TABLE1 column1 column2 SELECT MAX column1 FROM TABLE1 1 anotherColumn F
  • SQL 选择另一列中具有最大值的列

    我有一个看起来像这样的表 Name Group Value A 1 0 B 1 2 C 1 5 D 2 6 E 2 0 F 3 3 我想选择每组中具有最大值的名称 例如 有 3 个组 因此结果将是 Name C because it has
  • 如何从 PostgreSQL 数据库中删除表*或*视图?

    我在 PostgreSQL 数据库中有一个表或视图的名称 需要在单个 pgSQL 命令中删除 我怎样才能负担得起 我能够选择表单系统表来查找是否有任何具有此类名称但仍保留程序部分的表 SELECT count FROM pg tables
  • MySQL 更新具有多个值的查询

    我在数据库中有一个表 其记录如下 match id guess result 125 1 0 130 5 0 233 11 0 125 2 0 我的用户为每场比赛选择一个猜测 我有一个函数可以根据比赛的结果计算猜测的结果 如果猜测正确 结果
  • SQL Server 2012 中带有“AND”运算符的“LIKE”子句

    我的要求与该线程完全相同 如何在 SQL Server 中使用 JOIN LIKE 和 AND 运算符 https stackoverflow com questions 39745766 how to use join like with
  • 如何在条件持续时在Mysql中选择行

    我有这样的事情 Name Value A 10 B 9 C 8 意思是 这些值是按降序排列的 我需要创建一个新表 其中包含占总值 60 的值 所以 这可能是一个伪代码 set Total sum value set counter 0 fo
  • 从 LEFT OUTER JOIN 中删除重复项

    我的问题非常类似于限制 LEFT JOIN https stackoverflow com questions 757957 restricting a left join 有一个变体 假设我有一个表 SHOP 和另一个表 LOCATION
  • 我需要进行哪些更改才能让我的表在 AppEngine 的 BigTable 上运行?

    假设我有一个预订数据库 其中包括users user id fname lname 和他们的tickets ticket id user id flight no 以及相关的flights flight no airline departu
  • MySQL Workbench:如何将 mysql 数据库导出到 .sql 文件?

    我需要将 mysql 工作台中的数据库导出到文件 sql 该怎么办 在 MySql Workbench 版本 8 0 中 您只需按照以下步骤操作即可 Go to Server tab Go to 数据库导出 这会打开类似这样的东西 在中选择
  • 表中主键的最佳实践是什么? [关闭]

    Closed 这个问题是基于意见的 help closed questions 目前不接受答案 在设计表时 我养成了一种习惯 即有一列是唯一的 并且我将其作为主键 根据要求 可以通过三种方式实现 自动递增的标识整数列 唯一标识符 GUID
  • SQL准备语句如何通过多个可能的菜单选择进行选择?

    所以我有 4 个菜单选择 产品 位置 课程类型和类别 所有这些都可以为空 使用 JSF 编程 但这应该与这个问题无关 因为它是一个 SQL 问题 菜单选择将向托管 bean 发送用户选择的变量 并使用准备好的语句使用用户选择的菜单中的信息
  • 如何在oracle sql查询中提取括号之间的字符串

    我正在尝试从字符串中提取括号之间的值 我怎样才能做到这一点 例如 我有这个字符串 Gupta Abha 01792 我想得到括号之间的结果 即 01792 我正在尝试编写这样的查询 select substr Gupta Abha 0179
  • 与派生表的内连接

    我对连接派生表的基本语法有疑问 这是使用的基本语法吗 select from table1 a inner join select from table2 as T1 on 1 ID T1 ID 那行得通吗 您是在问加入两个子查询吗 尝试
  • 使用 min(datetime) 了解 SQL Server 行为

    长话短说 这只是我的一个愚蠢的假设 我确信一个专栏是一个日期时间 但它不是 所以不要指望在这个问题中找到任何有趣的东西 把它留在这里 以便民主党得到他的正确接受回答 我写了一个像这样的简单查询 SELECT ID MIN DateMadeA
  • 如何在 Hibernate 中使用 SELECT 进行 INSERT

    我需要在休眠中实现以下请求 insert into my table max column values select max id from special table where 如何在休眠中使用注释来做到这一点 Special tab
  • 选择具有按两列分组的最大值的行

    我见过很多关于此类问题的解决方案 尤其是这个SQL 仅选择列上具有最大值的行 https stackoverflow com questions 7745609 sql select only rows with max value on
  • Knex 中的表的别名

    我有一个 SQL 查询两次引用同一个表 并且我需要将该表别名为两个单独的别名 我不太清楚如何用 Knex 来编写它 有一个 单词 表和一个 用户 表 Words 表有两个外键 author id 和 winner id 引用 Users 表

随机推荐