【问题标题】:MySQL: Two of every setMySQL:每组两个
【发布时间】:2011-07-22 09:30:48
【问题描述】:

假设我有表“部门”(200 行)和“员工”(300,000 行)每个都有自己的详细信息 两者结合的向量表是“dep_emp”

CREATE TABLE IF NOT EXISTS `dep_emp` (
  `id` int(11) NOT NULL DEFAULT '0',
  `dep_id` int(11) NOT NULL DEFAULT '0',
  `emp_id` int(11) NOT NULL DEFAULT '0'
) ENGINE=MyISAM DEFAULT CHARSET=latin1;

我的问题是如何进行查询以获取每个部门的两名员工(任意两名员工)? 到目前为止,我的解决方案是这样的:

(SELECT * FROM `dep_emp` WHERE dep_id=1 LIMIT 2) UNION ALL
(SELECT * FROM `dep_emp` WHERE dep_id=2 LIMIT 2) UNION ALL
(SELECT * FROM `dep_emp` WHERE dep_id=3 LIMIT 2) ........etc

当然,每个部门都会这样做 {n} 次,所以如果我想为所有部门显示两个员工,那么我将不得不写 199 UNION ALL,这非常难看 任何其他解决方案 PS。有很多细节我已经从问题中移出以使事情变得更简单

【问题讨论】:

标签: php mysql


【解决方案1】:

这可能有效:

SELECT *
FROM Department
JOIN dep_emp USING (dep_id)
JOIN Employees USING (emp_id)
WHERE emp_id IN
  (SELECT emp_id
     FROM Employees
     JOIN dep_emp USING (emp_id)
    WHERE dep_emp.dep_id = Department.dep_id LIMIT 2)

虽然我没有测试它。

好吧,那没用。试试这个:

SELECT *
FROM Department
JOIN dep_emp USING (dep_id)
JOIN Employees USING (emp_id)
JOIN (SELECT emp_id, dep_id
        FROM dep_emp
    GROUP BY dep_id
       LIMIT 2) emp_2
  USING (emp_id, dep_id)

顺便说一句,不要忘记在表上放置一些索引。在 dep_emp 上,在两列上放置一个主键,并以相反的顺序在列上放置一个唯一键! (这样索引无论哪种方式都可以工作。)(顺便说一句,您不需要 dep_emp 中的 ID 列,至少在您显示的结构中不需要。)

【讨论】:

  • 最后一行会报错,没有“Department in subquery Unknown column 'Department.dep_id' in 'where子句'
  • @bhefny 您是否真的尝试过并报告错误?因为 MySQL 确实支持依赖子查询,这就是它。子查询查找父查询以查找表 Department。
  • 是的,我实际上是在报告测试后遇到的错误。这是我的数据: * MySQL 客户端版本:5.1.49 * PHP 扩展:mysqli * Apache/2.2.16 (Ubuntu)
  • @bhefny 试试我在答案中输入的新查询。
【解决方案2】:
SELECT d.*, e.* 
FROM Department AS d
  JOIN Employees AS e 
    ON e.id IN
         ( SELECT de.emp_id
           FROM dep_emp AS de
           WHERE de.dep_id = d.id
           LIMIT 2
         )

为每个部门获取两个emp_id 的另一种非常不同的方式:

SELECT dep_id
     , MIN(emp_id) AS emp_id_1
     , MAX(emp_id) AS emp_id_2
FROM dep_emp
GROUP BY dep_id

或(在单独的行中,因此可以将其连接到其他 2 个表):

    SELECT dep_id
         , MIN(emp_id) AS emp_id
    FROM dep_emp
    GROUP BY dep_id
  UNION ALL
    SELECT dep_id
         , MAX(emp_id)
    FROM dep_emp
    GROUP BY dep_id

第一个查询在 MySQL 中不起作用,因为 LIMIT 不允许在 IN 子查询中。这是另一种方法:

SELECT e.*
FROM
    ( SELECT DISTINCT dep_id
      FROM  dep_emp
    ) AS d
  JOIN
    dep_emp AS e
      ON  d.dep_id = e.dep_id
      AND e.emp_id <=
          COALESCE( ( SELECT de.emp_id
                      FROM dep_emp AS de
                      WHERE de.dep_id = d.dep_id
                      ORDER BY de.emp_id         --- OFFSET 1
                      LIMIT 1 OFFSET 1           --- to get 2 employess
                    )                            --- per department
                  , 9999999 )
ORDER BY e.dep_id
       , e.emp_id  

使用OFFSET x 获取每个部门的x+1 员工。

【讨论】:

  • “where 子句”中的未知列“d.id”
  • Max Min 解决方案是有限的,因为我想要每行 3 个
猜你喜欢
  • 2014-11-24
  • 2020-07-21
  • 1970-01-01
  • 2017-08-14
  • 1970-01-01
  • 1970-01-01
  • 2023-03-29
  • 1970-01-01
  • 2016-07-03
相关资源
最近更新 更多