从查询中检索特定键值并在查询中获取其对的计数

时间:2014-12-24 08:51:03

标签: php mysql sql select pivot

我有一个表lead_submission,其中包含特定格式的用户值,如

agent_name     qa_details
xxx      1001:|1083:|504:Yes|1009:|
ccc      504:Yes|1083:No|1008:|1009:|

现在我想要从两行得到504:Yes的计数

这些值来自另一个表paid_response

qno    paid_response
504     Yes
1083    No
1083    Possibly

<?php
//db connection goes here

$sql=mysql_query("select qno,paid_response from paid_response where qno='504' ");
while($rows=mysql_fetch_array($sql)) {    
$exqnos= $rows['qno'].'|'.$rows['paid_response'];
}

list($key,$val)=explode('|',$exqnos);
$exqno[$key]=$val;

foreach($exqno as $qno=>$value) {
$string .="qa_details LIKE '%|$qno:$value|%' ";  
}

$sql=mysql_query("SELECT count(agent_name) as agent_cnt,count($string) as ppicount FROM `lead_submission` WHERE $string "); ?>

               <table border="1">
                <thead>
                  <tr>
                    <th>CountAgent</th>
                    <th>504-COUNT</th>                      
                  </tr>

<?php
while($row=mysql_fetch_array($sql)) { ?>

     <tr style="color:red" >            
        <td><?php echo $row['agent_cnt']; ?></td>
        <td><?php echo $row['ppicount']; ?></td>            
        </tr>

<?php
}
?> 

现在通过这样做,504:Yes

计为2
CountAgent  504-COUNT
 2            2        //as u can see that `504:Yes` has occured two times in lead_submission table.

我的观点是我如何计算另一个组合说1083:No并在同一张表中显示计数

NB:- cant we just fetch the combination like `504:Yes` or `1083:No` or `1083:Yes` from paid_response table to maintain stability so that i dont have to change the query everytime. 

CountAgent  504-COUNT   1083-Count
  2           2           1        //how to get this count `1083:No` . as u can see it only appeared 1 times in `lead_submission` table

7 个答案:

答案 0 :(得分:5)

试试这个:

SELECT COUNT(DISTINCT ls.agent_name), 
       SUM(CASE WHEN pr.qno = 504 AND pr.paid_response = 'Yes' THEN 1 ELSE 0 END) AS '504-Count', 
       SUM(CASE WHEN pr.qno = 1083 AND pr.paid_response = 'No' THEN 1 ELSE 0 END) AS '1083-Count'
FROM lead_submission ls 
INNER JOIN paid_response pr
ON CONCAT('|', ls.qa_details, '|') LIKE CONCAT('%|', pr.qno, ':', pr.paid_response , '|%');

检查SQL FIDDLE DEMO

<强>输出

| COUNTAGENT | 504-COUNT | 1083-COUNT |
|------------|-----------|------------|
|          2 |         2 |          1 |

<强> :: EDIT ::

首先执行以下查询

SELECT GROUP_CONCAT('SUM(CASE WHEN pr.qno = ', qno, ' AND pr.paid_response = ''', paid_response,''' THEN 1 ELSE 0 END) AS ''', qno, '-Count''') 
FROM paid_response;

使用此查询的输出并构建您的最终查询,如下所示:

query = 'SELECT COUNT(DISTINCT ls.agent_name), ' + outputOfAboveQuery + ' FROM lead_submission ls NNER JOIN paid_response pr ON CONCAT('''|''', ls.qa_details, '''|''') LIKE CONCAT('''%|''', pr.qno, ''':''', pr.paid_response , '''|%''');';

在代码中执行此字符串,以便获取动态查询以获取计数

答案 1 :(得分:3)

<?php
$con = mysql_connect('localhost', 'root', '');
mysql_select_db('test',$con);

function countIt($checkArray)
{
    $checkVals = explode(',', $checkArray); 
    foreach($checkVals AS $val){
        list($qNo, $pRes) = explode(':', $val);
        $query = mysql_query("SELECT * FROM `paid_response` WHERE `qno`='$qNo' AND `paid_response`='$pRes'");
        if(mysql_num_rows($query) > 0){
            $query = mysql_query("SELECT * FROM `lead_submission` WHERE `qa_details` LIKE '%$val%'");
            $countArray[$val] = mysql_num_rows($query);
        } else {
            $countArray[$val] = 0;
        }
    }

    foreach($countArray AS $key=>$val){
        echo $key . '  =>  ' . $val . "<br/>";
    }
}

echo countIt('504:yes,1083:no,1083:yes,1083:possibly,504:no');

试试这个男人!

答案 2 :(得分:2)

回应他人的评论。您应该将模型标准化。

也就是说,提取您需要的结果并不是不可能的,只是解决方案效率低,不可扩展,新开发人员难以理解且不易扩展。

此外,更容易以长格式而不是宽格式提取数据,即

# wide data format
CountAgent  504-COUNT   1083-Count
  2           2           1  

VS。

# Long data format
dimension   count
CountAgent    2
504-Count     2
1083-Count    1

在PHP中,从长到宽的转换更容易(甚至可能不需要)。

SELECT 
CONCAT(pr.qno, ":", pr.paid_response) dimension,
COUNT(*) `count`
FROM lead_submission ls 
JOIN paid_response pr 
  ON ls.qa_details LIKE CONCAT("%", pr.qno, ":", pr.paid_response, "%")
-- insert where clause 
GROUP BY 1
UNION
SELECT 'count-agent' dimension,
COUNT(DISTINCT ls.agent_id) `count`
FROM lead_submission ls 
JOIN paid_response pr 
  ON ls.qa_details LIKE CONCAT("%", pr.qno, ":", pr.paid_response, "%")
-- insert where clause        
GROUP BY 1

在上面的查询中,where clause对于统一选择应该是相同的,我认为对于您的情况,它应采用以下形式:

WHERE CONCAT(pr.qno, ":", pr.paid_response) IN (<key-value pair 1>, <key-value pair 2>, ...)

返回以下结果:

DIMENSION       COUNT
1083:No         1
504:Yes         2
count-agent     2

这里是sqlfiddle demo

答案 3 :(得分:1)

假设数据的格式保持不变,您可以尝试这样的事情(未经测试):

$query[] = "SELECT COUNT(agent_name) as agent_cnt"; // number of agents in total

// Counts of each question/answer.
foreach ($exqno as $qno => $value) {
    $query[] = "(SELECT COUNT(agent_name) FROM lead_submission WHERE qa_details LIKE '%|$qno:$value|%') AS count_{$qno}";  
}

$full_query = implode(', ', $query) . " FROM lead_submission";

$sql = mysql_query( $full_query );

答案 4 :(得分:1)

SELECT productOwner_org_id, 
(SELECT COUNT(*) FROM tblProducts P2 WHERE P1.product_id=p2.product_id AND productDescription='Leisure at PER01 IVR Gas') AS '504-data',
(SELECT COUNT(*) FROM tblProducts P3 WHERE P1.product_id=p3.product_id AND productDescription='Leisure Plus at Centerpoint') AS '1083-data'
FROM tblProducts p1
WHERE productOwner_org_id = 'AEG01'
AND
(SELECT COUNT(*) FROM tblProducts P2 WHERE P1.product_id=p2.product_id AND productDescription='Leisure at PER01 IVR Gas') != 0
OR
(SELECT COUNT(*) FROM tblProducts P3 WHERE P1.product_id=p3.product_id AND productDescription='Leisure Plus at Centerpoint') != 0


;

你可以看到它有点难看。

A)您最好的选择是重新组织您的数据 要么 B)使用更多php逻辑以不同方式呈现/格式化数据

答案 5 :(得分:1)

在每个搜索案例中,计数代理可以不同。如果在上面的示例中您搜索了&#39; 504&#39; 1083:否&#39;那么两种情况都不是2。我建议您像这样修改脚本:

<?php
$array = array('504','1083');
//db connection goes here
$th="";
$tr="";
foreach($array as $arr) {
$srch=$arr;
$sql=mysql_query("select qno,paid_response from paid_response where qno=$srch ");
while($rows=mysql_fetch_array($sql)) {    
$exqnos= $rows['qno'].'|'.$rows['paid_response'];
}

list($key,$val)=explode('|',$exqnos);
$exqno[$key]=$val;

foreach($exqno as $qno=>$value) {
$string .="qa_details LIKE '%|$qno:$value|%' ";  
}
$sql=mysql_query("SELECT count(agent_name) as agent_cnt,count($string) as ppicount FROM `lead_submission` WHERE $string ");
        $th.="<th>CountAgent(".$arr.")</th><th>(".$arr.")-COUNT</th>";                      
while($row=mysql_fetch_array($sql)) {         
        $tr.="<td>".$row['agent_cnt']."</td><td>".$row['ppicount']."</td>";           
}
}
?> 
   <table border="1">
     <thead>
     <tr>
     <?php echo $th; ?>                     
     </tr>
     </thead>
     <tbody>
     <tr style="color:red" >            
     <?php echo $tr; ?>             
     </tr>
     </tbody>
     </table>

答案 6 :(得分:-1)

好的,这是不完整的答案。不完整,因为我不打扰为您编写特定查询。但我正在写关于如何做到这一点。

注意:阅读有关规范化的内容。你会看到你的错误。

如果您可以在开始时添加|来修改数据,即将1001:|1083:|504:Yes|1009:|设为|1001:|1083:|504:Yes|1009:|将对您有所帮助。

现在,您可以轻松搜索%|<ID>:%上的文字搜索,确保您通过将<ID>替换为该号码来找到504或1009或任何数字。

你读过标准化了吗?反正。

一旦你这样做,你现在可以做行到列的概念(我认为它被称为PIVOT查询,谷歌正常化时谷歌它。)。这里给出了一些例子

MySQL Row to Column 要么 Mysql query to dynamically convert rows to columns

很抱歉,答案不完整,但文字搜索是您最好的选择,并且在您在复杂查询中使用它之前,最好创建一个视图。但实际上它会非常缓慢地获取数据并且不推荐

希望你找到正常化...如果不试试这个:https://www.google.co.in/#q=normalization+in+database

哦,别忘了索引该栏目......