0

我有这个代码

<?php
function Random($numchar)  
{  
$categories = "83 76 168 102";  
$array=explode(" ",$categories);  
shuffle($array);  
$newstring = implode($array,",");
return substr($newstring, 0, $numchar);  

}
$numbers = Random(216);
$res = str_replace(",","','",$numbers);
$cats = '\''.$res.'\'';
$news = mysql_query("SELECT 
item.id AS itemid, 
item.cid AS itemcid, 
SUBSTRING_INDEX(item.url, '/', 3) AS itemurl, 
item.title AS itemtitle, 
item.top AS itemtop, 
images.id AS imgid, 
images.img AS imagesimg, 
images.item_id AS imagesitemid,
folders.id AS foldersid,
channels.id AS channelsid,
channels.parent AS channelsparent
FROM item, images, folders, channels 
WHERE 
item.id = images.item_id
AND item.cid = channels.id
AND channels.parent = folders.id
AND channels.parent = '$cat'
AND FIELD(item.cid, $cats)
ORDER BY 
itemtop DESC, RAND(), images.item_id DESC 
LIMIT 20");

?>

每次刷新页面时,代码都会从变量 $categories 中定义的类别之一返回 20 个项目。我只想显示每个类别的 5 个项目。是否可以按照我的意图使用单个查询?我想腾出空间,以便可以平等地显示所有类别的项目。

有没有其他方法可以优化查询?

4

2 回答 2

1

为了从每个类别中获取 5 个项目,您必须对每个类别运行单独的子查询,限制为 5,然后将它们组合在一起。这是一个例子:

SELECT
  *
FROM (
  (SELECT
    item.id AS itemid, 
    item.cid AS itemcid, 
    SUBSTRING_INDEX(item.url, '/', 3) AS itemurl, 
    item.title AS itemtitle, 
    item.top AS itemtop, 
    images.id AS imgid, 
    images.img AS imagesimg, 
    images.item_id AS imagesitemid,
    folders.id AS foldersid,
    channels.id AS channelsid,
    channels.parent AS channelsparent
  FROM
    item,
    images,
    folders,
    channels
  WHERE 
    item.id = images.item_id
    AND item.cid = channels.id
    AND channels.parent = folders.id
    AND channels.parent = '$cat[0]'
    AND FIELD(item.cid, $cats[0])
  LIMIT 5)

  UNION ALL

  (SELECT
    item.id AS itemid, 
    item.cid AS itemcid, 
    SUBSTRING_INDEX(item.url, '/', 3) AS itemurl, 
    item.title AS itemtitle, 
    item.top AS itemtop, 
    images.id AS imgid, 
    images.img AS imagesimg, 
    images.item_id AS imagesitemid,
    folders.id AS foldersid,
    channels.id AS channelsid,
    channels.parent AS channelsparent
  FROM
    item,
    images,
    folders,
    channels
  WHERE 
    item.id = images.item_id
    AND item.cid = channels.id
    AND channels.parent = folders.id
    AND channels.parent = '$cat[1]'
    AND FIELD(item.cid, $cats[1])
  LIMIT 5)

  UNION ALL

  (SELECT
    item.id AS itemid, 
    item.cid AS itemcid, 
    SUBSTRING_INDEX(item.url, '/', 3) AS itemurl, 
    item.title AS itemtitle, 
    item.top AS itemtop, 
    images.id AS imgid, 
    images.img AS imagesimg, 
    images.item_id AS imagesitemid,
    folders.id AS foldersid,
    channels.id AS channelsid,
    channels.parent AS channelsparent
  FROM
    item,
    images,
    folders,
    channels
  WHERE 
    item.id = images.item_id
    AND item.cid = channels.id
    AND channels.parent = folders.id
    AND channels.parent = '$cat[2]'
    AND FIELD(item.cid, $cats[2])
  LIMIT 5)
)sub_query

ORDER BY 
  itemtop DESC, RAND(), sub_query.item_id DESC

您可能希望在子查询中添加 order by 以定义为每个类别返回的 5 个。您可能还需要重新定义您$cat的定义方式。希望这可以帮助。

于 2013-06-07T20:24:33.443 回答
0

您可以尝试使用用户变量...不确定php如何/是否会处理它,但是使用原始sql这样的东西应该可以工作(未经测试,但您应该明白,请参阅http://www.xaprb.com /blog/2006/12/07/how-to-select-the-firstleastmax-row-per-group-in-sql/了解更多详情):

set @num := 0, @cid := '';

SELECT 
item.id AS itemid, 
item.cid AS itemcid, 
SUBSTRING_INDEX(item.url, '/', 3) AS itemurl, 
item.title AS itemtitle, 
item.top AS itemtop, 
images.id AS imgid, 
images.img AS imagesimg, 
images.item_id AS imagesitemid,
folders.id AS foldersid,
channels.id AS channelsid,
channels.parent AS channelsparent,
@num := if(@cid = item.cid, @num + 1, 1) as row_number,
@cid := cid as dummy
FROM item, images, folders, channels 
WHERE 
item.id = images.item_id
AND item.cid = channels.id
AND channels.parent = folders.id
AND channels.parent = '$cat'
AND FIELD(item.cid, $cats)
ORDER BY 
itemtop DESC GROUP, RAND(), images.item_id DESC
GROUP BY item.id, item.cid, item.title
having row_number <= 5;
于 2013-06-07T20:31:09.103 回答