0

我在这里查看了大约 18 个其他帖子,大多数人都在问如何删除记录而不仅仅是隐藏它们。所以我的问题是:我有一个数据库,其中包含与位置相关的工作人员。许多工作人员与多个地点相关联。我想要做的是只显示 mysql 结果中列出的第一个位置并跳过其他位置。我有将表链接在一起的 sql 查询,除了它为那些在其他位置的工作人员多次显示相同的信息之外,它还可以工作,所以示例如下:

在此处输入图像描述

这是我目前的sql语句

    SELECT staff_tbl.staffID, staff_tbl.firstName, staff_tbl.middleInitial, staff_tbl.lastName,
     location_tbl.locationID, location_tbl.staffID, 
    officelocations_tbl.locationID, officelocations_tbl.officeName, staff_title_tbl.title_ID,
     staff_title_tbl.staff_ID, titles_tbl.titleID, titles_tbl.titleName

    FROM staff_tbl 

    INNER JOIN location_tbl ON location_tbl.staffID = staff_tbl.staffID 
    INNER JOIN officelocations_tbl ON location_tbl.locationID = officelocations_tbl.locationID
    INNER JOIN staff_title_tbl ON staff_title_tbl.staff_ID = staff_tbl.staffID 
    INNER JOIN titles_tbl ON staff_title_tbl.title_ID = titles_tbl.titleID 

我的 php 是

      <?php do { ?>
<tr>
  <td><?php echo $row_rs_Staff_Info['firstName']; ?>&nbsp; <?php echo $row_rs_Staff_Info['lastName']; ?></td>
  <td><?php echo $row_rs_Staff_Info['titleName']; ?>&nbsp; </td>
  <td><?php echo $row_rs_Staff_Info['officeName']; ?>&nbsp; </td>

</tr>
<?php } while ($row_mysqlResult = mysql_fetch_assoc($rs_mysqlResult)); ?>

我想知道的是有没有一种方法使用 php 只选择为每个人列出的第一个条目并显示它,然后跳过其他两个。我在想这可以通过可能将staffID添加到一个数组中来完成,如果他们在那里跳过staff_title_tbl中列出的下一个但不太确定如何写它。任何帮助都会非常感谢您提前。

4

3 回答 3

2

你可以使用mysql的DISTINCT,像这样:

SELECT DISTINCT(staff_tbl.staffID), staff_tbl.firstName, staff_tbl.middleInitial (.. etc)

我希望这有帮助

于 2012-10-07T00:06:22.583 回答
1

您可以在 上使用子查询来location_tbl为每个员工选择一个位置

SELECT staff_tbl.staffID, 
  staff_tbl.firstName, 
  staff_tbl.middleInitial, 
  staff_tbl.lastName,
  location_tbl.locationID, 
  location_tbl.staffID, 
  officelocations_tbl.locationID, 
  officelocations_tbl.officeName, 
  staff_title_tbl.title_ID,
  staff_title_tbl.staff_ID, 
  titles_tbl.titleID, 
  titles_tbl.titleName
FROM staff_tbl 
INNER JOIN
(
  select max(locationID) locationID, staffID
  from location_tbl 
  group by staffID
) location_tbl 
  ON location_tbl.staffID = staff_tbl.staffID 
INNER JOIN officelocations_tbl 
  ON location_tbl.locationID = officelocations_tbl.locationID
INNER JOIN staff_title_tbl 
  ON staff_title_tbl.staff_ID = staff_tbl.staffID 
INNER JOIN titles_tbl 
  ON staff_title_tbl.title_ID = titles_tbl.titleID
于 2012-10-07T00:03:30.883 回答
0

除了使用 DISTINCT(staffID) 来限制重复的员工列表之外,您的查询还可以使用一些额外的清理:

1) 使用表别名,这样您就不必为每列引用整个表名

2)您的 SELECT 列列表中有冗余数据:

location_tbl。locationID == officelocations_tbl。位置ID

职员表。员工 ID == location_tbl。职员 ID == 职员_title_tbl员工编号

staff_title_tbl。标题_ID == 标题_tbl。标题ID

仅仅因为您在连接中使用列并不意味着您必须在 SELECT 语句中引用该列。如果这些列确实具有不同的值,那么您将很难在连接语句中配对 2 列。

3)不一致:你真的应该重命名staff_title_tbl。staff_ID只是 staffID 和 staff_title_tbl。title_ID到 titleID 以便它们匹配另一个表的列名。请注意,在下面的清理查询中,我们如何在列名匹配的人员 ID 和 locationID 上使用 USING(),但在不匹配时必须写入更长的 ON。使您的名称保持一致,以便在您的程序中您不必回头查看表格来查看您命名某物的方式。

4) 虽然为了清楚起见,您可能希望写出 INNER JOIN,但如果您愿意,可以只使用 JOIN,因为如果没有列出其他特定类型的连接,这是默认的 JOIN 类型。

SELECT  DISTINCT(s.staffID)
        ,s.firstName
        ,s.middleInitial
        ,s.lastName
        ,l.locationID
        ,ol.officeName
        ,st.title_ID
        ,t.titleName
FROM    staff_tbl           AS s
JOIN    location_tbl        AS l
USING   (staffID)
JOIN    officelocations_tbl AS ol
USING   (locationID)
JOIN    staff_title_tbl     AS st
ON      st.staff_ID = s.staffID 
JOIN    titles_tbl          AS t
ON      st.title_ID = t.titleID

另外为了您的信息,一种在 PHP 中使用您对多行的原始查询执行此操作的方法,但我很惊讶原始 PHP 工作,因为您在一个地方有一个名为 $row_rs_Staff_Info 的查询行集和 $row_mysqlResult其他...

<?php 
$unique = array();
do {
    $key = $row_mysqlResult['firstName'].$row_mysqlResult['lastName'];

    //if ok being last location, newer values will overwrite old for same key
    $unique[$key] = $row_rs_Staff_Info;

    //OR

    //if must be first location, check for key & dont overwrite if already set
    if(!array_key_exists($key, $unique)){
        $unique[$key] = $row_mysqlResult;
    }
} while ($row_mysqlResult = mysql_fetch_assoc($rs_mysqlResult));

foreach($unique as $k => $v){?>
<tr>
  <td><?php echo $v['firstName']; ?>&nbsp; <?php echo $v['lastName']; ?></td>
  <td><?php echo $v['titleName']; ?>&nbsp; </td>
  <td><?php echo $v['officeName']; ?>&nbsp; </td>
</tr>
<?php } ?>

php 数组键必须是唯一的,因此您可以添加应该进行唯一连接的值组合,如果相同的键值再次出现在结果中,它将用新值覆盖该键的现有值。但是,除非您还需要更大的数据集来存储页面上的其他内容并且您不想查询两次,否则请在 SQL 而不是 PHP 中进行优化,这样您就不会为不打算使用的数据浪费服务器资源。

编辑

我从您提供的小提琴链接中加载了 sql,并且 group by 确实消除了重复的 Alexander Walsh 行。

SELECT      s.staffID
            ,s.firstName
            ,s.middleInitial
            ,s.lastName
            ,l.locationID
            ,ol.officeName
            ,st.title_ID
            ,t.titleName
FROM        staff_tbl           AS s
JOIN        location_tbl        AS l
USING       (staffID)
JOIN        officelocations_tbl AS ol
USING       (locationID)
JOIN        staff_title_tbl     AS st
ON          st.staff_ID = s.staffID 
JOIN        titles_tbl          AS t
ON          st.title_ID = t.titleID
GROUP BY    (staffID)

结果(针对表格宽度编辑了一些列):

staffID firstName   lastName    officeName      titleName
1       Alexander   Walsh       Seattle         Consultant
2       Bernadette  Ace         Sacramento      Consultant
3       Bert        McElway     San Antonio     Associate Consultant
5       Peter       Wallace     San Francisco   Senior Consultant
于 2012-10-08T03:35:49.620 回答