mysql in(...) 1次取出当前记录及上1条下1条记录, 且使用了主键作为索引
2012-10-23 01:18
477 查看
mysql 1次取出当前记录及上1条下1条记录,效果非常好!
对于让mysql一次取出当前记录,及上1条、下1条,目前网上那条sign( ID - 3 )...的sql语句反正我是看得云里雾里,
自己写了一条比较清晰的sql语句,就是select ... in ( 4 , 5 , 6 ) 的语句,其中4、5、6通过union 连接起来mysql的任务就完成了。然后用php将mysql给出的数据处理一下,ok。
由于才取3条数据, mysql语句怎么union都不会有什么性能问题的。
-------------------------------------------
一次取出编号为7的记录 和 它的上一条、下一条
SELECT * FROM article
where id in(
SELECT max( id ) FROM article WHERE id < 7
union
select 7
union
SELECT min( id ) FROM article WHERE id > 7
)
结果::
技术细节见下:
1.article表结构: aid( 主键 ) title content ... ,
2.sql语句,
3.php执行和处理 .
<?php
$id = 5; // 假设http://localhost/mycms/?ac=show&id=5 id为5
$sql = "
SELECT * FROM article
where
`aid` in(
SELECT max( `aid` ) FROM article WHERE `aid` < {$id}
union all
SELECT {$id}
union all
SELECT min( `aid` ) FROM article WHERE `aid` > {$id}
)
ORDER BY aid ASC
LIMIT 0,3
";
$list = db::get_all( $sql );
empty( $list ) && exit( '该文章不存在.' );
// 再次遍历, 判断文章编号是否存在.
$aid_exists = false;
$row = array();
foreach ( $list as $n=>$line ){
if ( $id == $line['aid'] ){
$aid_exists = true;
$row = $line; // 当前记录
break;
}
}
false === $aid_exists && exit( '该文章不存在.' );
// 它的后1条
$row['prev'] = isset( $list[$n-1] ) ? $list[$n-1] : false;
// 它的前1条
$row['next'] = isset( $list[$n+1] ) ? $list[$n+1] : false;
// 载入show.html模版
tpl( 'show' , $row );
?>
上述得到 $row 的结构:: ( 黄色背景色是当前的数据, prev next分别是上1条、下1条 )
$row = Array(
[aid] => 5
[title] => 叶斯算法(bayesian)介绍
[prev] => Array(
[aid] => 4
[title] => ffffffffff
)
[next] => Array (
[aid] => 6
[title] => 模式四要素
)
)
----------------
再在show.html 里面写上如下代码::
<style>
#prev_next span{ display: inline-block; width: 260px ; }
</style>
<!-- 前1条、后1条 -->
<div id="prev_next">
<span>
<下一篇:
<?php
if( $next ) {
$next_short = substr( $next['content'] , 0 , 150 );
echo "<a href=\"?ac=show&id={$next['aid']}\" title=\"下1篇:{$next['title']}\n\r{$next_short}\" >".substr( $next['title'] , 0 , 30 ).'</a>';
}
else{
echo ' 没有了 ';
}
?>
</span>
<span style="text-align:right;">
上一篇:
<?php
if( $prev ) {
$prev_short = substr( $prev['content'] , 0 , 150 );
echo "<a href=\"?ac=show&id={$prev['aid']}\" title=\"上1篇:{$prev['title']}\n\r{$prev_short}\" >".substr( $prev['title'] , 0 , 30 ).'</a>';
}
else{
echo ' 没有了 ';
}
?>
>
</span>
</div>
结果是相当满意,如下图::
性能分析::
explain一下上面那条语句:
使用了key: PRIMARY 主键 作为索引,所以性能是可以的.
对于让mysql一次取出当前记录,及上1条、下1条,目前网上那条sign( ID - 3 )...的sql语句反正我是看得云里雾里,
自己写了一条比较清晰的sql语句,就是select ... in ( 4 , 5 , 6 ) 的语句,其中4、5、6通过union 连接起来mysql的任务就完成了。然后用php将mysql给出的数据处理一下,ok。
由于才取3条数据, mysql语句怎么union都不会有什么性能问题的。
-------------------------------------------
一次取出编号为7的记录 和 它的上一条、下一条
SELECT * FROM article
where id in(
SELECT max( id ) FROM article WHERE id < 7
union
select 7
union
SELECT min( id ) FROM article WHERE id > 7
)
结果::
技术细节见下:
1.article表结构: aid( 主键 ) title content ... ,
2.sql语句,
3.php执行和处理 .
<?php
$id = 5; // 假设http://localhost/mycms/?ac=show&id=5 id为5
$sql = "
SELECT * FROM article
where
`aid` in(
SELECT max( `aid` ) FROM article WHERE `aid` < {$id}
union all
SELECT {$id}
union all
SELECT min( `aid` ) FROM article WHERE `aid` > {$id}
)
ORDER BY aid ASC
LIMIT 0,3
";
$list = db::get_all( $sql );
empty( $list ) && exit( '该文章不存在.' );
// 再次遍历, 判断文章编号是否存在.
$aid_exists = false;
$row = array();
foreach ( $list as $n=>$line ){
if ( $id == $line['aid'] ){
$aid_exists = true;
$row = $line; // 当前记录
break;
}
}
false === $aid_exists && exit( '该文章不存在.' );
// 它的后1条
$row['prev'] = isset( $list[$n-1] ) ? $list[$n-1] : false;
// 它的前1条
$row['next'] = isset( $list[$n+1] ) ? $list[$n+1] : false;
// 载入show.html模版
tpl( 'show' , $row );
?>
上述得到 $row 的结构:: ( 黄色背景色是当前的数据, prev next分别是上1条、下1条 )
$row = Array(
[aid] => 5
[title] => 叶斯算法(bayesian)介绍
[prev] => Array(
[aid] => 4
[title] => ffffffffff
)
[next] => Array (
[aid] => 6
[title] => 模式四要素
)
)
----------------
再在show.html 里面写上如下代码::
<style>
#prev_next span{ display: inline-block; width: 260px ; }
</style>
<!-- 前1条、后1条 -->
<div id="prev_next">
<span>
<下一篇:
<?php
if( $next ) {
$next_short = substr( $next['content'] , 0 , 150 );
echo "<a href=\"?ac=show&id={$next['aid']}\" title=\"下1篇:{$next['title']}\n\r{$next_short}\" >".substr( $next['title'] , 0 , 30 ).'</a>';
}
else{
echo ' 没有了 ';
}
?>
</span>
<span style="text-align:right;">
上一篇:
<?php
if( $prev ) {
$prev_short = substr( $prev['content'] , 0 , 150 );
echo "<a href=\"?ac=show&id={$prev['aid']}\" title=\"上1篇:{$prev['title']}\n\r{$prev_short}\" >".substr( $prev['title'] , 0 , 30 ).'</a>';
}
else{
echo ' 没有了 ';
}
?>
>
</span>
</div>
结果是相当满意,如下图::
性能分析::
explain一下上面那条语句:
使用了key: PRIMARY 主键 作为索引,所以性能是可以的.
相关文章推荐
- MySQL 使用自增ID主键和UUID 作为主键的优劣比较详细过程(从百万到千万表记录测试)
- 写出一条Sql语句,取出表A中的第31条到第40条记录。表A以自动增长的ID作为主键。(注意:ID可能不是连续的)
- MySQL 使用自增ID主键和UUID 作为主键的优劣比较详细过程(从百万到千万表记录测试)
- 如何写出一条SQL语句:取出表A中第31~40条记录(SQLServer,以自动增长的ID作为主键
- 写出一条Sql语句:取出表A中第31到第40记录(SQLServer,以自动增长的ID作为主键,注意:ID可能不是连续的。
- 写出一条Sql语句:取出表A中第31到第40记录(SQLServer,以自动增长的ID作为主键,注意:ID可能不是连续的。
- 取出表A中第31到第40记录(SQLServer,以自动增长的ID作为主键,注意:ID可能不是连续的
- 写出一条SQL语句:取出表A中第31到40行记录(SQLserver,以自增长的ID作为主键,注意:
- MySQL 使用自增ID主键和UUID 作为主键的优劣比较详细过程(从百万到千万表记录测试)
- MySQL 使用自增ID主键和UUID 作为主键的优劣比較具体过程(从百万到千万表记录測试)
- MySQL 使用自增ID主键和UUID 作为主键的优劣比较详细过程(从百万到千万表记录测试)
- 使用Logstash + Elasticsearch作为大数据索引、分析工具
- 实体类中有主键,数据库中主键是自增的,使用linq插入记录时,由于实体类有数据产生报错的解决方法
- 请求量限制方法-使用本地Cache记录当前请求量[坑]
- 为什么分布式数据库中不使用uuid作为主键?
- SOLR:APACHE版solr环境搭建及作为Hbase二级索引使用
- 获取GridView中RowCommand的当前选中行的索引或主键Id
- 不要用把无序GUID既作为主键又作为聚集索引
- SharePoint 2013 使用JQuery 一些记录如(SharePoint js 获得当前用户)等基本操作。
- Oracle学习记录之使用自定义函数和触发器实现主键动态生成