【问题标题】:Retrieving specific key-values from a query and fetch count of their pair in query从查询中检索特定键值并在查询中获取它们对的计数
【发布时间】:2015-02-22 09:45:43
【问题描述】:

我有一个表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

【问题讨论】:

  • 为什么要这样存储数据?如果你能正确地规范化信息,这会更容易,而且通过这种方式来解决这个问题可能是一个更好的主意。
  • 你能举个例子吗?
  • '没有这个并发症。'复杂性来自于您没有选择一种好的格式来保存数据。你宁愿标准化你的数据。
  • 所以你的意思是我没有办法从这里数数?
  • 删除 | 不是一个好主意和 : 。你如何区分问题 504 和答案 504?

标签: php mysql sql select pivot


【解决方案1】:

好的,这是不完整的答案。不完整,因为我懒得为你写具体的查询。但我正在写如何做到这一点。

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

如果您可以通过在数据开头添加| 来修改您的数据,即将1001:|1083:|504:Yes|1009:| 设置为|1001:|1083:|504:Yes|1009:| 对您有很大帮助。

现在,您可以轻松地在 %|&lt;ID&gt;:% 上搜索文本搜索,这可以确保您找到 504 或 1009 或任何数字,方法是用该数字替换 &lt;ID&gt;

你读过规范化吗?无论如何。

一旦你这样做了,你现在就可以做 Row to Column 概念(我认为它被称为 PIVOT Queries,当你 google 规范化时用 google 搜索它。)。这里给出了一些例子

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

抱歉,答案不完整,但文本搜索是您最好的选择,最好先创建一个视图,然后再将其用于复杂查询。但实际上获取数据会非常慢,并且不推荐

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

哦,别忘了为该列建立索引...

【讨论】:

    【解决方案2】:

    试试这个:

    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 , '''|%''');';
    

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

    【讨论】:

    • 虽然这样的答案可能适用于这种特定情况(及其变体),但这不是推荐的路径。绝对的最佳解决方案是首先规范化数据库。谷歌“数据库范式”。感谢@Saharsh 无论如何都能找到解决方案。
    • 但如果1083:No 之类的组合在paid_response 表中更改为1083:Yes,那么我必须将此查询更改为是。我们不能只从paid_response 表中获取组合以保持稳定性
    • @black 如果您想执行类似的操作,然后从paid_response thable 获取记录,然后在您的代码中使用动态创建SUM(CASE WHEN pr.qno = 504 AND pr.paid_response = 'Yes' THEN 1 ELSE 0 END) AS '504-Count', 这部分构建查询,在此您必须替换@987654331 @ 到 your fetched qno column dataYes 到“您获取的paid_response 列数据”。所以你可以为此创建动态查询
    • @shah 我没有得到你的代码。如果我粘贴你编辑的第一个查询,它会在 phpmyadmin 的表头中回显查询。您能否详细说明您的代码和comment.thnx 以获得响应和快速解决方案。我只想从paid_response 表中获取组合。
    • @black 我已经展示了你必须编写的 PHP 代码的一部分。首先,您必须在 PHP 方法中调用我的第一个查询并将该查询的输出存储在一个变量中,然后使用上述变量构建第二个查询并在 PHP 中执行该查询,您将获得所需的输出。
    【解决方案3】:

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

    $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】:
      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】:

        呼应别人的cmets。您可能应该标准化您的模型。

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

        此外,提取长格式的数据比提取宽格式的数据更容易,即

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

        对比

        # 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

        【讨论】:

          【解决方案6】:

          计数代理在每个搜索案例中可能不同。如果在上面的示例中搜索“504”、“1083:No”,那么在这两种情况下都不是 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>
          

          【讨论】:

          • 这样你可以在数组的开头插入你的搜索变量。
          • ty 用于响应,但您的代码不起作用Warning: mysql_fetch_array() expects parameter 1 to be resource, boolean given 并且表格标题仅显示第二个数组值,例如您在数组中给出了 504,1083,因此它显示 为 1083 而不是504.跨度>
          • 它工作正常,只传递一个值,如数组中的 504 或 1083。但不是同时
          • 所以它的计数不准确(ag​​ent_name),它的显示count(agent_name)作为它的显示count($string)。意思是如果1083:No是1代理计数是1。如果1083:No是0 代理计数显示为 0
          • 现在试试请更正并且没有mysql_real_escape_string
          【解决方案7】:
          <?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');
          

          试试这个人!

          【讨论】:

            猜你喜欢
            相关资源
            最近更新 更多
            热门标签