MySQL 一次查询中的多项选择检索嵌套数组

MySQL multiple selects in one query retrieve nested array

[更新]

我正在尝试 select 来自一个 table 的数据,但尝试以不同的顺序获取它们

SELECT * FROM 
(
  SELECT * FROM videos ORDER BY timestamp DESC
) mostrecent

UNION ALL

SELECT * FROM
( 
  SELECT * FROM videos ORDER BY timestamp ASC
) oldest

现在这将以不同的顺序检索记录。最新视频和最旧视频...

foreach($table as $key=>$value)
{
$row_tmb[$key] = $value;
}
$array[] = $row_tmb;

打印数据时

print_r($array);

我明白了

Array ( [0] => Array ( [vid] => 1 [title] => title1 [timestamp] => newer) 
        [1] => Array ( [vid] => 2 [title] => title2 [timestamp] => older
        //from second select...
        [2] => Array ( [vid] => 2 [title] => title2 [timestamp] => older
        [3] => Array ( [vid] => 1 [title] => title1 [timestamp] => newer
)

我要

Array('newest' => Array ( 
        [0] => Array ( [vid] => 1 [title] => title1 [timestamp] => newer) 
        [1] => Array ( [vid] => 2 [title] => title2 [timestamp] => older))
        //from second select...
Array('oldest' => Array (
        [0] => Array ( [vid] => 2 [title] => title2 [timestamp] => older
        [1] => Array ( [vid] => 1 [title] => title1 [timestamp] => newer))

您可以在 select 语句中使用外部查询,如下所示:

select
    *
from
    (
        SELECT
            'Newest',col1,col2,etc
        FROM
            (
            SELECT 
                * 
            FROM 
                videos 
            ORDER BY 
                timestamp DESC
            )mostrecent
        UNION ALL
        SELECT
            'Oldest',col1,col2,etc
        FROM
            (
            SELECT 
                * 
            FROM 
                videos 
            ORDER BY 
                timestamp DESC
            )oldest
    ) someTable
order by
    1 asc

这将首先按 Newest/Oldest 对结果进行排序,然后按您的顺序排序。

这不会像您显示所需的输出那样为您提供两个数组,但它几乎可以为您提供您想要的相同内容,只是在一个数组中除外。但是,您可以简单地检查 PHP 代码中的第一列,然后将其放入正确的数组中以获得所需的嵌套数组。

编辑:为派生 table 添加了别名。不要挑剔,但在您编写 "Doesn't even work" 的同时,您可能会发现遗漏并进行有效查询。来吧伙计,这里的答案是有帮助的,而不是总是为你做你的工作:)

我知道这将是一个理想的答案,但至少我不必 mysql 查询两次。 因为我知道每次选择只需要两条记录。

$newest = array($videos[0], $videos[1]);
$oldest = array($videos[2], $videos[3]);

现在这甚至让检索到 html...

时更容易使用

MySQL documentation 明确指出:对单个 SELECT 语句使用 ORDER BY 并不意味着行在最终结果中出现的顺序,因为默认情况下是 UNION生成一组无序的行。

我建议你使用一个简单的查询:

SELECT *
FROM videos
ORDER BY timestamp DESC

获取 PHP 数组中的数据,然后使用 PHP 代码复制它并根据需要组合它。这是一些使用 mysqli 的示例代码。使用 PDO 类似:

// You should add a LIMIT to the query or it will take a lot of time and consume
// a lot of memory when the table gets bigger (several thousand rows)
$query  = 'SELECT * FROM videos ORDER BY timestamp DESC';
$result = mysqli_query($connection, $query);

// Retrieve the data
$data = array();
while ($row = mysqli_fetch_assoc($result)) {
    $data[] = $row;
}

// Use the retrieved data to get the combined result
$array = array(
    'newest' => $data,
    'oldest' => array_reverse($data),
);

更新:

假设列 timestamp 包含一个整数值(时间戳),您可以使用如下查询从 MySQL 获得相同的结果:

(
    SELECT *, 'newest' AS source, timestamp AS sortColumn
    FROM videos
)
UNION ALL
(
    SELECT *, 'oldest' AS source, -timestamp AS sortColumn
    FROM videos
)
ORDER BY sortColumn DESC

如果 timestamp 列不是整数值而是 DATE,则使用 FROM_UNIXTIME(timestamp) AS sortColumn 代替。这个想法是计算一个可用于最终排序的值(在 UNION 级别)并将其存储在新列 sortColumn.

source 列用于 PHP 以了解每条记录所属的组(最新记录与最旧记录)。

// The lists of data split by source
$array = array(
    'newest' => array(),
    'oldest' => array(),
);
// Retrieve the data, put it into the correct list
while ($row = mysqli_fetch_assoc($result)) {
    $array[$row['source']] = $row;
}

备注:对于大中型表(千行以上)会运行慢,因为不能使用索引。对于这种大小的表,无论如何 select 所有记录都没有多大意义。你可能会这样写:

(
    SELECT *, 'newest' AS source, timestamp AS sortColumn
    FROM videos
    ORDER BY timestamp DESC
    LIMIT 100
)
UNION ALL
(
    SELECT *, 'oldest' AS source, nbVotes AS sortColumn
    FROM videos
    ORDER BY timestamp ASC
    LIMIT 100
)
ORDER BY sortColumn DESC

到 select 最近的 100 行和最旧的 100 行。最终结果从按 timestamp 降序排列的最新记录开始(最新的在前)然后是按收到的投票数(nbVotes 列)降序排列的最旧的记录(我假设没有视频有更多超过 13 亿张选票)。