繁体   English   中英

如何在有限的、任意排序的记录集中找到单个记录的*位置*?

[英]How to find the *position* of a single record in a limited, arbitrarily ordered record set?

MySQL

假设您只想通过某个 id 检索单个记录,但您想知道如果您在一个大的有序集中遇到它,它的 position 会是什么。

一个典型的例子是照片库。 你登陆一张照片,但系统必须知道它在整个画廊中的偏移量是多少。

我想我可以使用自定义索引字段来跟踪位置,但是在 SQL 中必须有更优雅的方式。

因此,首先您创建一个虚拟表,其中 position # 按您的 ORDER BY 排序,然后您 select 是该集合中最高的一个。 那是更大结果集中的 position。 如果您不按唯一值/值集排序,您可能会遇到问题......

如果您在 (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;

不需要额外的表,为什么不只计算记录呢?

您知道它们的显示顺序(可能会有所不同),但您知道这一点。

你也知道当前记录的ID; 假设它是在日期订购的:

记录的偏移量是日期<该日期的记录总数。

SELECT COUNT(1) FROM ... WHERE date < "the-date"

这为您提供了可以用作其他查询的偏移量的数字...

并不真地。 我认为 Oracle 给你一个“ROWID”或类似的东西,但大多数人不给你一个。 自定义排序,例如数据库中的一列,告诉您想要 position 画廊中的条目是好的,因为您永远无法确定 SQL 会按照您认为它们应该在的顺序将事物放入表中。

由于您不具体说明您使用的是什么数据库,因此您可以在 SQL Server 2005 中使用

SELECT 
  ROW_NUMBER() OVER (ORDER BY PhotoID)
  , PhotoID
FROM dbo.Photos

您没有说您使用的是什么 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

该查询将 select所有照片(全表扫描),然后挑选出您要求的照片 - 不是性能查询!

我建议如果您真的需要此信息,则应将其存储。

假设 position 完全由 id 决定,难道不就是把所有 id 值较小的记录都统计一下那么简单吗?:

select
    po.[id]
    ...
    ((select count(pi.[id]) from photos pi where pi.[id] < po.[id]) + 1) as index
    ...
from photos po
...

我不确定这种查询的性能影响是什么,但我认为返回大量记录可能是一个问题。

您必须了解“应用程序密钥”和“技术密钥”之间的区别。

存在技术密钥的唯一目的是使项目独一无二。 它通常在 INTEGER 或 BIGINT 中,生成(身份等)。 该键用于定位数据库中的对象,快速找出已持久化的 object(ID 必须 > 0,因此默认 ID == 0 的 object 尚未在数据库中)等。

应用程序密钥是您需要在应用程序上下文中理解 object 的东西。 在这种情况下,它是图库中照片的排序。 这对数据库没有任何意义。

考虑有序列表:这是大多数语言的默认设置。 您有一组项目,由索引访问。 对于数据库,此索引是应用程序键,因为数据库中的集合是无序的(或者数据库不保证任何排序,除非您指定 ORDER BY)。 出于同样的原因,对查询结果进行分页非常痛苦:数据库真的不喜欢“位置”的概念。

因此,您必须做的是添加一个索引行(即 INTEGER 说明您的图像在图库中的哪个 position ;不是用于更快访问的数据库索引,即使您应该在此列上创建索引...)并维护那。 对于每次插入,您必须UPDATE index = index + 1 where index >= insertion_point等。

是的,这很糟糕。 我知道的唯一解决方案:使用 ORM 框架为您解决这个问题。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM