MySql 查询的最佳方式?虚拟表?由于需要唯一列而返回重复行

标签 mysql database-design join

我有一个为我正在制作的网站制作的数据库,其中包含员工列表。这将是一个类似列表的网格,其中包含每个员工的照片、姓名、电话号码等。

这是我的第一个数据库设计,我为此感到非常自豪......但我是一个新手,所以我确信它在某些方面效率低下。

我无法找到查询网站制作元素的最佳方式。

1) 我应该使用虚拟表吗?还是我应该只使用一个查询并为每位员工循环查询?

2) 一些员工将拥有不止一个管辖权。现在我有:

select employees.firstName, employees.lastName, employees.phone, employees.position,
    employees.picture, jurisdictions.jurisdiction
from employees
    inner join(jurisdictions cross join departments cross join user_jurisdictions)
    on (employees.deptID = departments.deptID
        AND user_jurisdictions.userID = employees.userID
        AND user_jurisdictions.jurID = jurisdictions.jurID)

哪个会返回:

+-----------+----------+--------------+-----------------+---------+--------------+
| firstName | lastName | phone        | position        | picture | jurisdiction |
+-----------+----------+--------------+-----------------+---------+--------------+
| John      | Smith  | 210-226-3232 | Senior Manager   |/pics/jpeg1|South America|
| John      | Smith  | 210-226-3232 | Senior Manager   |/pics/jpeg1|London       |
+-----------+----------+--------------+-----------------+---------+--------------+

由于员工拥有额外的管辖权,如何创建查询以删除重复的行?像什么?

+-----------+----------+--------------+---------+---------+--------------+------------+
| firstName | lastName | phone        | position| picture | jurisdiction |Jurisdiction|
+-----------+----------+--------------+---------+---------+--------------+------------+
| John      | Smith  | 210-226-3232 | Manager |/pics/jpeg1| South America|London      |
+-----------+----------+--------------+-----------------+---------+-------------------+

这是我的 mysql 架构:

employees
--------------------
userID (primary key)
firstName
lastName
phone
fax
position
picture
deptID (foreign key references departments(deptID)) 



departments
--------------------
deptID (primary key)
department

jurisdictions
-----------------
jurID (primary key)
jurisdiction


user_jurisdictions
--------------------------
userID(foreign key references employees(userID)) 
jurID(foreign key references jurisdictions(jurID))


triger: 
 after_employees_insert | INSERT | employees | begin
insert into user_jurisdictions(userID) values (new.userID);

最佳答案

您可以按员工对结果进行分组并使用 MySQL 的 GROUP_CONCAT()汇总员工管辖范围的函数:

SELECT   employees.firstName,
         employees.lastName,
         employees.phone,
         employees.position,
         employees.picture,
         GROUP_CONCAT(jurisdictions.jurisdiction)
FROM     employees
    JOIN departments        USING (deptID)
    JOIN user_jurisdictions USING (userID)
    JOIN jurisdictions      USING ( jurID)
GROUP BY employees.userID

但是,这会将司法管辖区聚合成一个分隔字符串(这使得很难区分多个司法管辖区和包含分隔符的单个司法管辖区:人们可以选择不太可能在司法管辖区名称中使用的分隔符,但它仍然受制于诸如字符串长度限制之类的问题,在我看来,这从根本上是懒惰的)。

更好的方法可能是将此类聚合留给应用程序代码的更高级别。例如,使用 PDO :

$dbh = new PDO("mysql:dbname=$dbname", $username, $password);

$qry = $dbh->query('
  SELECT   employees.userID
           employees.firstName,
           employees.lastName,
           employees.phone,
           employees.position,
           employees.picture,
           jurisdictions.jurisdiction
  FROM     employees
      JOIN departments        USING (deptID)
      JOIN user_jurisdictions USING (userID)
      JOIN jurisdictions      USING ( jurID)
  ORDER BY employees.userID
');

$row = $qry->fetch();
while ($row) {
  $current_user = $row['userID'];

  // handle $current_user initialisation
  do {
    // handle user $row
  } while ($row = $qry->fetch() and $row['userID'] == $current_user);
  // handle $current_user termination

}

当然,这样做的缺点是会产生更大的结果集,该结果集必须由 RDBMS 生成并传输到更高级别的代码/由更高级别的代码处理。

关于MySql 查询的最佳方式?虚拟表?由于需要唯一列而返回重复行,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/13961542/

相关文章:

mysql - 从 MYSQL 中的每个组中选择最后一个条目

PHP:在 SQL 表上的特定行处启动 while 循环

MySql Left Join 返回除第一个匹配行之外的所有匹配行

php - 选择连接 MYSQL

php - 将链接数据从一个表中的一行提取到另一表中的多行

mysql - 如何获取下表中每位顾客的预订数量

mysql - SQL子查询优化,如何先执行子查询

database - Cassandra 中非均匀范围数据的均匀分区

mysql - 修复损坏的 UTF8 字符 MYSQL

mysql - SQL:如何使用相应的外键为表中的每个现有元素插入一行到表中?