我有两个嵌套查询,第二个是在我遍历第一个结果时运行。我很想让MySQL服务器做这项工作而不是PHP,但我无法弄清楚如何将这两者结合起来。
第一个查询:
SELECT post_id,
MAX(CASE WHEN meta_key = 'size' THEN meta_value END) size,
MAX(CASE WHEN meta_key = 'adlink' THEN meta_value END) adlink,
MAX(CASE WHEN meta_key = 'frontpage' THEN meta_value END) frontpage,
MAX(CASE WHEN meta_key = 'expiration' THEN meta_value END) expiration,
MAX(CASE WHEN meta_key = 'image1' THEN meta_value END) image1,
MAX(CASE WHEN meta_key = 'image2' THEN meta_value END) image2,
MAX(CASE WHEN meta_key = 'image3' THEN meta_value END) image3,
MAX(CASE WHEN meta_key = 'image4' THEN meta_value END) image4,
MAX(CASE WHEN meta_key = 'iframe' THEN meta_value END) iframe,
MAX(CASE WHEN meta_key = 'location' THEN meta_value END) location,
MAX(CASE WHEN meta_key = 'sublocation' THEN meta_value END) sublocation
FROM wp_postmeta WHERE post_id in
(SELECT post_id from wp_postmeta
WHERE meta_value LIKE 'Run Of Site') GROUP BY Post_id
然后,迭代结果,我们从另一个表中获取图像,因为'image1'等只是第一组结果中的post id号码:
SELECT meta_value FROM wp_postmeta
WHERE post_id IN
(SELECT meta_value from wp_postmeta
WHERE post_id = " . $row{'post_id'} ." AND meta_key like 'image%')
这是查看PHP迭代的完整代码(我知道它需要更好的格式化以实现可读性):
$rosads = mysql_query("SELECT post_id,
MAX(CASE WHEN meta_key = 'size' THEN meta_value END) size,
MAX(CASE WHEN meta_key = 'adlink' THEN meta_value END) adlink,
MAX(CASE WHEN meta_key = 'frontpage' THEN meta_value END) frontpage,
MAX(CASE WHEN meta_key = 'expiration' THEN meta_value END) expiration,
MAX(CASE WHEN meta_key = 'image1' THEN meta_value END) image1,
MAX(CASE WHEN meta_key = 'image2' THEN meta_value END) image2,
MAX(CASE WHEN meta_key = 'image1' THEN meta_value END) image3,
MAX(CASE WHEN meta_key = 'image2' THEN meta_value END) image4,
MAX(CASE WHEN meta_key = 'iframe' THEN meta_value END) iframe,
MAX(CASE WHEN meta_key = 'location' THEN meta_value END) location,
MAX(CASE WHEN meta_key = 'sublocation' THEN meta_value END) sublocation
FROM wp_postmeta WHERE post_id in (SELECT post_id from wp_postmeta WHERE meta_value LIKE 'Run Of Site') GROUP BY Post_id");
if (!$rosads) { // add this check.
die('Invalid query: ' . mysql_error());
}
while ($row = mysql_fetch_array($rosads)) { // ######### ITERATE THROUGH THE LIST
if ($row{'size'} == "Premium"){
if ($row{'iframe'}){
$premium = $premium . '<div name="PREMIUM'.$row{'post_id'}.'" style="float:left;">'.$row{'iframe'}.'</div>'."\n";
}else{
$images = mysql_query("SELECT meta_value FROM wp_postmeta where post_id IN(SELECT meta_value from wp_postmeta WHERE post_id = " . $row{'post_id'} ." AND meta_key like 'image%')");
$premium = $premium . "<div name=\"".$row{'post_id'}."\" class=\"multipleslides\" >";
while ($row2 = mysql_fetch_array($images)) {
$premium = $premium . "\t<a target=\"_blank\" href=\"" . $row{'adlink'} ."\"><img src=\"/wp-content/uploads/" .$row2{'meta_value'} ."\"></a>\r\n";
}
$premium = $premium . "</div><br>";
}
/* ### TEST STUFF ####
echo $row{'post_id'} . ", " . $row{'size'} . ", " . $row{'adlink'} . ", " . $row{'frontpage'} . ", " . $row{'expiration'} . ", " . $row{'image1'} . ", " . $row{'image2'} . ", " . $row{'image3'} . ", " . $row{'image4'} . ", " . 1$row{'location'} . ", " . $row{'sublocation'} . ", " . $row{'iframe'} . "<hr>";
*/
} // ###### END THIS ITERATION ####
答案 0 :(得分:1)
您也可以将查询用作列,但请确保您的子查询应返回一条安全方面的记录我在子查询中添加了LIMIT 1
,或者如果有多于1的结果,您可以删除限制并可以使用GROUP_CONCAT(meta_value)
但请注意它的默认限制为1024个字符
SELECT wpm.post_id,
MAX(CASE WHEN wpm.meta_key = 'size' THEN wpm.meta_value END) size,
MAX(CASE WHEN wpm.meta_key = 'adlink' THEN wpm.meta_value END) adlink,
MAX(CASE WHEN wpm.meta_key = 'frontpage' THEN wpm.meta_value END) frontpage,
MAX(CASE WHEN wpm.meta_key = 'expiration' THEN wpm.meta_value END) expiration,
MAX(CASE WHEN wpm.meta_key = 'image1' THEN wpm.meta_value END) image1,
MAX(CASE WHEN wpm.meta_key = 'image2' THEN wpm.meta_value END) image2,
MAX(CASE WHEN wpm.meta_key = 'image3' THEN wpm.meta_value END) image3,
MAX(CASE WHEN wpm.meta_key = 'image4' THEN wpm.meta_value END) image4,
MAX(CASE WHEN wpm.meta_key = 'iframe' THEN wpm.meta_value END) iframe,
MAX(CASE WHEN wpm.meta_key = 'location' THEN wpm.meta_value END) location,
MAX(CASE WHEN wpm.meta_key = 'sublocation' THEN wpm.meta_value END) sublocation,
(
SELECT
meta_value
FROM
wp_postmeta
WHERE post_id IN
(SELECT
meta_value
FROM
wp_postmeta
WHERE post_id = wpm. post_id
AND meta_key LIKE 'image%')
LIMIT 1) images
FROM wp_postmeta wpm WHERE wpm.post_id IN
(SELECT post_id FROM wp_postmeta
WHERE meta_value LIKE 'Run Of Site') GROUP BY wpm.post_id
对于group_concat()
(
SELECT
GROUP_CONCAT(meta_value)
FROM
wp_postmeta
WHERE post_id IN
(SELECT
meta_value
FROM
wp_postmeta
WHERE post_id = wpm. post_id
AND meta_key LIKE 'image%')
) images
答案 1 :(得分:1)
要提高效率,请将IN (subquery)
替换为等效的连接操作,并确保您具有合适的索引。
在第一个查询中,将其替换为:
FROM wp_postmeta WHERE post_id in
(SELECT post_id from wp_postmeta
WHERE meta_value LIKE 'Run Of Site') GROUP BY Post_id
用这个:
FROM wp_postmeta m
JOIN ( SELECT r.post_id
FROM wp_postmeta r
WHERE r.meta_value LIKE 'Run Of Site'
GROUP BY r.post_id
) q
ON q.post_id = m.post_id
GROUP BY m.post_id
AND 将SELECT列表中的post_id
引用更改为m.post_id
(以避免“模糊列”引用错误。)
对于第二个查询,将“IN(子查询)”替换为JOIN操作:
SELECT t.meta_value
FROM wp_postmeta t
JOIN ( SELECT q.meta_value
FROM wp_postmeta q
WHERE q,meta_key LIKE 'image%'
AND q.post_id = " . $row{'post_id'} ."
) s
ON s.meta_value = t.meta_value
ORDER BY t.meta_value
组合这两个查询是有问题的,因为第二个查询可以返回多个匹配post_id的行。
要返回结果集,我们需要定义结果集的外观。
有三种一般方法。简而言之,
一种方法是“重复”第一个查询返回的值,但这看起来不适合您当前的代码。 “fetch next”需要检查post_id是否已被处理,并忽略重复值。 (这是几个ORM框架用于提高效率的方法;它们具有剥离重复项的代码层,并创建不同的对象。)
另一种方法是从第二个查询返回固定数量的值,每个值都作为第二个查询中的列。请注意,SQL SELECT语句必须定义要返回的列数以及每个列的数据类型。查询运行时无法动态更改。如果我们可以指定要返回的行数的有限上限,那么我们可以创建SQL文本来实现这一点,尽管结果语句可能有点令人生畏,并且存在一些性能问题。
返回“set”值的最方便方法是将它们作为单个字符串返回,并带有分隔符。 MySQL GROUP_CONCAT
函数是一种非常方便的方法,但有一些限制。首先,我们必须在值之间有一个分隔符;默认分隔符是一个逗号,但可以使用任何字符(“管道”字符似乎很流行......为避免歧义,我们必须保证分隔符字符不会出现在连接在一起的值中。其他限制是函数返回的大小;最大大小受MySQL max_allowed_packet
变量的限制。