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 亿张选票)。
[更新]
我正在尝试 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 亿张选票)。