一点点复杂的sql行位置

时间:2010-01-10 07:32:56

标签: sql mysql pagination

基本上我有专辑,有50张图片初始化..现在,如果我显示图像列表,我知道从哪一行显示(显示:20到30的50),意味着从20 - 30显示10行现在问题是,我想选择一个图像,但仍然显示它被选中的位置,所以我可以来回移动,但也保持位置。

就像我选择了第5张图片,其中id是'sd564',我想要显示(50张图片中的6张),意味着你看到50张图片中的第6张..如果我得到下一行ID并显示,那么,我想展示(50张图片中的7张)。

好吧,我可以很容易地从分页指针做这一切,比如在url中说(在= 5之后,在= 6之后)......它随着位置移动,但是如果我没有这个(在= 6之后)并且只是有一个身份证,我怎么能这样做?

我不想使用(之后= 6)也因为它的动态网站和图片添加和删除,所以定位chnages并与其他人共享并返回相同的旧链接,那么这将是错误的位置。

我应该为此运行什么样的SQL查询?

目前我有

select * from images where id = 'sd564'; 

显然我需要在查询中添加限制或其他一些东西来获取我想要的东西,或者可能运行另一个查询来获得结果,同时保持这个旧查询。无论如何我只想要定位。我希望你能帮我解决这个问题

示例: http://media.photobucket.com/image/color%20splash/aly3265/converse.jpg

sample http://img41.imageshack.us/img41/5631/viewing3of8240.png

相册查询请求(请查看下面的帖子)

select images.* from images, album
where album_id = '5'
and album_id = image_album_id
order by created_date DESC
limit ....;

3 个答案:

答案 0 :(得分:2)

假设每个created_date album_id是唯一的{(1}},album_id} created_date中的所有行都是唯一的,那么:

images

将可靠地为您提供图像及其位置。请理解,只有在整个图像表中(album_id,created_date)是唯一的情况下,这才能可靠地工作。如果情况并非如此,则该位置不可靠,并且您可能看不到select i1.*, count(*) as position from images i1 inner join images i2 on i1.album_id = i2.album_id -- get all other pics in this album and i1.created_date >= i2.created_date -- in case they were created before this pic where i1.album_id = 5 group by i1.created_date 引起的所有照片。另请注意,像这样的GROUP BY子句,仅列出GROUP BY列表中出现的一些列(在本例中为SELECT)在大多数RDBMS-es中无效。有关该问题的详细讨论,请参阅:http://dev.mysql.com/tech-resources/articles/debunking-group-by-myths.html

通过这样做:

images.*

您在第4个位置选择图像(请注意select i1.*, count(*) as position from images i1 inner join images i2 on i1.album_id = i2.album_id -- get all other pics in this album and i1.created_date >= i2.created_date -- in case they were created before this pic where i1.album_id = 5 group by i1.created_date having count(*) = 4

通过这样做:

having     count(*) = 4

您选择位置为1到10的所有照片(再次注意select i1.*, count(*) as position from images i1 inner join images i2 on i1.album_id = i2.album_id -- get all other pics in this album and i1.created_date >= i2.created_date -- in case they were created before this pic where i1.album_id = 5 group by i1.created_date having count(*) between 1 and 10 子句。)

当然,如果你只想要一个特定的图像,你可以简单地做:

having

这将正确报告相册中图像的位置(当然,假设image_id在图像表中是唯一的)。在这种情况下,您不需要having子句,因为您已经精确定位了所需的图像。

答案 1 :(得分:0)

从你在这里说的话:

  

不想使用(在= 6之后)也因为它的动态网站和图片添加和删除,所以定位chnages并与其他人共享并返回相同的旧链接,那么这将是错误的位置。

我觉得这根本不是SQL问题。问题是fotos的位置对于搜索结果集是本地的。为了可靠地按位置导航,您需要制作某种快照(无双关语)。也就是说,您需要有一些方法在浏览数据集时“冻结”数据集。

一种简单的方法是执行搜索,并将结果缓存在实际的当前数据存储区之外。例如,您可以在数据库中使用“临时表”,只需将其存储在临时文件中,或者存储在某个内存缓存层中(如果您有mem)。使用此模型,您可以让用户从缓存中浏览结果集,并且您需要在用户会话结束时清除缓存(或者在一些超时后,您不希望因为某些用户不愿意杀死您的服务器'退出)

另一种方法,就是让自己偶尔撒谎。假设您有10张图像的结果页面,典型搜索可以提供50页的结果。好吧,你可以简单地向一个固定数量的项目发送一个结果集,比如向客户端发送100张照片(那么10页)。这些搜索结果将成为您的快照,并包含对实际图片的引用。如果要将URL存储在数据库中,而不是二进制数据,则此引用只是URL。或者您可以在那里存储数据库ID。无论如何,允许用户浏览初始结果集,并且可能他们从不浏览整个集合。如果他们这样做,您将在服务器端重新执行查询以获取下一页的页面。如果在最终位于1..100的平均时间内添加了许多照片,那么用户将会看到过时的数据:这是他们为拥有这么多时间所付出的代价,他们可以允许他们浏览10页10张照片。

(当然,你应该根据自己的喜好调整参数,但你明白了我的想法。)

如果您不想“撒谎”并且人们可以可靠地浏览他们搜索的所有结果非常重要,您可以扩展数据库模式以支持该级别的快照。现在假设照片只有两个操作,即“添加”和“删除”,你的照片表中会有一个TIMESTAMP_ADDED和一个TIMESTAMP_REMOVED。添加时,在数据库中执行INSERT,并使用当前时间戳填充TIMESTAMP_ADDED。对于您希望用于存储时间戳的任何数据类型,TIMESTAMP_REMOVED将填充理论最大值(对于此特定情况,我可能会转到INT列并只是存储UNIX_TIMESTAMP)在删除时,您< em>不 DELETE来自db的行,而是通过更新TIMESTAMP_REMOVED列将其标记为已删除,并将其设置为当前时间戳。现在,当您必须进行搜索时,可以使用如下查询:

SELECT    *
FROM      photo
WHERE     timestamp_added   < timestamp_of_initial_search
AND       timestamp_removed > timestamp_of_initial_search
AND      ...various search criteria...
ORDER BY ...something
LIMIT    ...page offset and num items in page...

timestamp_of_initial_search是执行特定标准集的初始搜索的时间戳。您应该在用户浏览特定搜索结果时将其存储在应用程序会话中,以便您可以在获取页面所需的后续查询中使用它。前两个WHERE标准用于实现快照。条件timestamp_added < timestamp_of_initial_search确保我们只能看到在执行搜索的时间戳之前添加的照片。条件timestamp_removed > timestamp_of_initial_search确保我们只搜索在初始搜索执行时尚未删除的内容。

当然,您仍然需要对标记为删除的照片执行某些操作。您可以为已删除时间戳的所有照片安排定期物理删除,这些照片小于当前搜索结果集中的任何一个。

答案 2 :(得分:0)

如果我正确理解您的问题,您可以使用Row_Number()函数(在SQL Server中)。要获得所需的结果,您可以使用与此类似的查询:

select images1.* from 
    (SELECT ROW_NUMBER() OVER (ORDER BY image_album_id) as rowID,(SELECT COUNT(*) FROM images) AS totCount, * FROM images) images1
JOIN album ON (album_id = images1.image_album_id)
where album_id = '5' 
order by images1.image_album_id 
limit ....;

这里的images.rowid给你行和images.totCount的位置给你总行数。

希望它有所帮助。

Thnks。