PDO选择并计算IN HAVING DISTINCT以显示在下拉列表中

时间:2014-01-04 04:19:54

标签: php mysql sql pdo

我有这个mysql选择工作很棒。它返回正确的数据。我似乎无法确定上下文的正确位置,因此它将显示在下拉选项选择的末尾。      该语句返回正确的位置名称

$statement = $pdo->prepare("SELECT locationname FROM location WHERE locationname IN (SELECT locationname FROM location_user WHERE custnum= :custnum GROUP BY locationname HAVING COUNT( DISTINCT email) < 6 )");
  $statement->execute(array(':custnum' => $session->custnum));

 while($row = $statement->fetch(PDO::FETCH_ASSOC)){
echo'<option value="'.$row['locationname'].'">'.$row['locationname'].'('. $row['COUNT(total)'] .')</option>';    
}

这是我尝试获取每个招数的总数

$statement = $pdo->prepare("SELECT locationname, COUNT(custnum) AS total FROM location WHERE  locationname IN (SELECT locationname FROM location_user WHERE custnum= :custnum GROUP BY locationname HAVING COUNT( DISTINCT email) < 6 )");
$statement->execute(array(':custnum' => $session->custnum));

while($row = $statement->fetch(PDO::FETCH_ASSOC)){
echo'<option value="'.$row['locationname'].'">'.$row['locationname'].'('. $row['total'] .')</option>';    
}

这是我的表格

       table location                            table location_user
custnum   |   locationname             custnum   |    locationname  |   email    |  userlevel
   1           location1                 1            location1       1me@you.com       3
   1           location2                 1            location1       1me@you.com       1
                                         1            location1       2me@you.com       2
                                         1            location1       3me@you.com       2
                                         1            location1       4me@you.com       2
                                         1            location1       5me@you.com       2
                                         1            location2       1me@you.com       2
                                         1            location2       1me@you.com       3

第一个选择返回

 location1()
 location2()

第二个选择返回

 location1(2)

我实际上需要查询所执行的不同电子邮件的计数,并且仅返回表中不同电子邮件的位置名称,但是如何获取每个位置名称的不同电子邮件的实际数量。

此选择将检索DISTINCT电子邮件的总数,但如何将这两者合并为我的while循环?

$statement2 = $pdo->prepare("SELECT COUNT(email) AS total FROM location_user WHERE custnum= :custnum GROUP BY locationname HAVING COUNT( DISTINCT email) < 6");
$statement2->execute(array(':custnum' => $session->custnum));

这是Peter的帮助下的工作版本以及Tin的一点点刺激。

 $statement = $pdo->prepare("SELECT l.locationname, COUNT(DISTINCT lu.email) AS total 
 FROM location l LEFT JOIN location_user lu ON l.locationname = lu.locationname AND l.custnum = lu.custnum WHERE l.custnum = :custnum GROUP BY l.locationname HAVING COUNT(DISTINCT lu.email)  < 5 ");
 $statement->execute(array(':custnum' => $session->custnum));

 while($row = $statement->fetch(PDO::FETCH_ASSOC)){
 echo'<option value="'.$row['locationname'].'">'.$row['locationname'].'('. $row['total'] .')</option>';    
 }

这是另一个版本,我正在努力跳过将位置添加到表中的用户。此用户将始终具有用户级别&gt; 2. uselevel仅作为1-9之间的值放在location_user表中。所以我仍然需要位置名称,但我不希望他们的位置包含在计数中。我刚刚意识到我实际上可以走更好的路线,因为我想要计算的唯一电子邮件的用户级别为2.我使用不同的电子邮件来过滤掉用户级别1.我会试一试。下面的版本删除了我在location_user表中没有的位置,但它返回了正确的计数。

     SELECT l.locationname, COUNT(lu.userlevel) AS total 
     FROM location l LEFT JOIN location_user lu
     ON l.locationname = lu.locationname
     AND l.custnum = lu.custnum
     WHERE l.custnum = :custnum
     AND lu.userlevel = 2
     GROUP BY l.locationname
     HAVING COUNT(lu.userlevel) < 6

2 个答案:

答案 0 :(得分:2)

UPDATE2:根据您的评论。试试这种方式

SELECT l.locationname, COUNT(DISTINCT lu.email) AS total 
  FROM location l LEFT JOIN location_user lu
    ON l.locationname = lu.locationname
   AND l.custnum = lu.custnum
   AND lu.userlevel < 3 -- consider only users with user level < 3
 WHERE l.custnum = ?
 GROUP BY l.locationname 
HAVING COUNT(DISTINCT lu.email) < 6

示例输出:

| LOCATIONNAME | TOTAL |
|--------------|-------|
|    location1 |     5 |
|    location2 |     1 |
|    location3 |     0 |

这是 SQLFiddle 演示

答案 1 :(得分:0)

您实际上不需要从表location查询,因为您已经拥有表locationname中的location_user字段

SELECT locationname, count(DISTINCT email) as total FROM location_user WHERE custnum = :custnum GROUP BY locationname HAVING count(DISTINCT email) < 6