的MySQL
假设你想要通过某个id只检索一条记录,但是如果你在一个大的有序集中遇到它,你想知道它的位置是什么。
案例就是照片库。你落在一张照片上,但系统必须知道它在整个画廊中的偏移量。
我想我可以使用自定义索引字段来跟踪位置,但在SQL中必须有更优雅的方式。
答案 0 :(得分:2)
因此,首先创建一个虚拟表,其位置#按您的ORDER BY排序,然后从该集合中选择最高的一个。这是更大结果集中的位置。如果您没有按唯一值/值组排序,则可能会遇到问题...
如果您在(photo_gallery_id,date_created_on)上创建索引,它可能会进行索引扫描(取决于照片的分布),这应该比表扫描更快(假设您的gallery_id不是照片的90%)或什么)。
SELECT @row := 0;
SELECT MAX( position )
FROM ( SELECT @row := @row + 1 AS position
FROM photos
WHERE photo_gallery_id = 43
AND date_created_on <= 'the-date-time-your-photo-was'
ORDER BY date_created_on ) positions;
答案 1 :(得分:0)
不是真的。我认为Oracle给你一个“ROWID”或类似的东西,但大多数不给你一个。自定义排序,比如数据库中的一列,告诉您想要在库中输入条目的位置是好的,因为您永远无法确定SQL会按照您认为的顺序将事物放入表中。
答案 2 :(得分:0)
由于您没有具体说明您正在使用的数据库,因此在SQL Server 2005中您可以使用
SELECT
ROW_NUMBER() OVER (ORDER BY PhotoID)
, PhotoID
FROM dbo.Photos
答案 3 :(得分:0)
您没有说出您正在使用的DBMS,并且“解决方案”会相应地发生变化。在Oracle中,你可以这样做(但我不鼓励你!):
select photo, offset
from
( select photo
, row_number() over (partition by gallery_id, order by photo_seq) as offset
from photos
)
where id = 123
该查询将选择所有照片(全表扫描),然后选择您要求的照片 - 而不是高性能查询!
我建议如果你确实需要这个信息应该存储。
答案 4 :(得分:0)
假设位置仅由id确定,那么它不会像计算id值较小的所有记录一样简单吗?:
select
po.[id]
...
((select count(pi.[id]) from photos pi where pi.[id] < po.[id]) + 1) as index
...
from photos po
...
我不确定此类查询的性能影响是什么,但我认为返回大量记录可能是个问题。
答案 5 :(得分:0)
您必须了解“应用程序密钥”和“技术密钥”之间的区别。
技术密钥的唯一目的是使项目独一无二。它通常在INTEGER或BIGINT中生成(身份,等等)。此键用于定位数据库中的对象,快速找出已保留的对象(ID必须> 0,因此具有默认ID == 0的对象尚未在DB中),等等。
应用程序密钥是您需要了解应用程序上下文中的对象的东西。在这种情况下,它是图库中照片的排序。这对数据库没有任何意义。
思考有序列表:这是大多数语言的默认值。您有一组由索引访问的项目。对于数据库,此索引是应用程序密钥,因为数据库中的集是无序的(或者除非您指定ORDER BY,否则数据库不保证任何排序)。出于同样的原因,从查询中分页查询是一件很痛苦的事情:数据库真的不喜欢“位置”的想法。
所以你必须做的是添加一个索引行(即一个INTEGER,它表示你的图像在图库中的哪个位置;不是用于更快访问的数据库索引,即使你应该在这个列上创建一个索引......并保持这一点。对于每次插入,您必须UPDATE index = index + 1 where index >= insertion_point
等
是的,很糟糕。我所知道的唯一解决方案:使用ORM框架为您解决此问题。
答案 6 :(得分:0)
不需要额外的表,为什么不只计算记录呢?
您知道它们的显示顺序(可能会有所不同),但您知道。
您还知道当前记录的ID;让我们说它是按日期订购的:
记录的偏移量是使用日期<1计算的记录总数。那个日期。
SELECT COUNT(1) FROM ... WHERE date < "the-date"
这为您提供了可用作其他查询的偏移量的数字......