从查询中检索特定键值并在查询中获取它们对的计数
Posted
技术标签:
【中文标题】从查询中检索特定键值并在查询中获取它们对的计数【英文标题】: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? 【参考方案1】:好的,这是不完整的答案。不完整,因为我懒得为你写具体的查询。但我正在写如何做到这一点。
注意:阅读规范化。你会看到你的错误。
如果您可以通过在数据开头添加|
来修改您的数据,即将1001:|1083:|504:Yes|1009:|
设置为|1001:|1083:|504:Yes|1009:|
对您有很大帮助。
现在,您可以轻松地在 %|<ID>:%
上搜索文本搜索,这可以确保您找到 504 或 1009 或任何数字,方法是用该数字替换 <ID>
。
你读过规范化吗?无论如何。
一旦你这样做了,你现在就可以做 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 data
和 Yes
到“您获取的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,因此它显示 <?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');
试试这个人!
【讨论】:
以上是关于从查询中检索特定键值并在查询中获取它们对的计数的主要内容,如果未能解决你的问题,请参考以下文章
PHP 如何从 AJAX 调用中发布多个数组/json 值并在同一个 SQL 查询中运行它们?