来自sql结果的重复信息

时间:2012-10-06 23:55:30

标签: php mysql

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

enter image description here

这是我目前的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中列出的下一个,但不太确定如何以这种方式编写它。任何帮助都会非常感谢你。

3 个答案:

答案 0 :(得分:2)

您可以使用mysql的DISTINCT,如下所示:

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

我希望这会有所帮助

答案 1 :(得分: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

答案 2 :(得分:0)

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

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

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

location_tbl。 locationID == officelocations_tbl。 locationID

staff_tbl。 staffID == location_tbl。 staffID == staff_title_tbl。 staff_ID

staff_title_tbl。 title_ID == titles_tbl。 titleID

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

3)不一致:您确实应该将staff_title_tbl。 staff_ID 重命名为staffID,将staff_title_tbl。 title_ID 重命名为titleID,以便它们与其他表的列名匹配。请注意下面的清理查询中我们如何在列名称匹配的staffID和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