当前位置: 首页 > 面试题库 >

Postgres下一个/上一个行SQL查询

秦炜
2023-03-14
问题内容

我在Postgres 9.1数据库中具有以下表结构,但是理想的解决方案应该是与数据库无关的(如果可能的话):

Table: users
|id|username|
|1 |one     |
|2 |two     |
|3 |three   |

Table: items
|id|userid|itemname|created  |
|1 |1     |a       |timestamp|
|2 |1     |b       |timestamp|
|3 |1     |c       |timestamp|
|4 |2     |d       |timestamp|
|5 |2     |e       |timestamp|
|6 |2     |f       |timestamp|
|7 |3     |g       |timestamp|
|8 |3     |h       |timestamp|
|9 |3     |i       |timestamp|

我有一个查询(用于视图),该查询提供了下一个和上一个item.id。

例如

View: UserItems
|id|userid|itemname|nextitemid|previtemid|created  |
|1 |1     |a       |2         |null      |timestamp|
|2 |1     |b       |3         |1         |timestamp|
|3 |1     |c       |4         |2         |timestamp|
|4 |2     |d       |5         |3         |timestamp|
|5 |2     |e       |6         |4         |timestamp|
|6 |2     |f       |7         |5         |timestamp|
|7 |3     |g       |8         |6         |timestamp|
|8 |3     |h       |9         |7         |timestamp|
|9 |3     |i       |null      |8         |timestamp|

我可以使用以下查询执行此操作:

SELECT
  DISTINCT i.id AS id,
  i.userid AS userid,
  i.itemname AS itemname,
  LEAD(i.id) OVER (ORDER BY i.created DESC) AS nextitemid,
  LAG(i.id) OVER (ORDER BY i.created DESC) AS previtemid,
  i.created AS created
FROM items i
  LEFT JOIN users u
  ON i.userid = u.id
ORDER BY i.created DESC;

您可以帮助解决以下问题:

1)有没有办法让ID包裹,即

  • nextitemid列最后一行中的NULL itemid应该为1
  • previtemid列第一行中的NULL itemid应该是9

2)是否有一种有效的方法来按用户ID分组下一个和上一个itemid,例如

注意: 在此示例中,一个用户的itemid是连续的,对于真实数据则不是这种情况,每个用户的itemid都是交错的。

View: UserItems
|id|userid|itemname|nextitemid|previtemid|nextuseritemid|prevuseritemid|created  |
|1 |1     |a       |2         |9         |2             |3             |timestamp|
|2 |1     |b       |3         |1         |3             |1             |timestamp|
|3 |1     |c       |4         |2         |1             |2             |timestamp|
|4 |2     |d       |5         |3         |5             |6             |timestamp|
|5 |2     |e       |6         |4         |6             |4             |timestamp|
|6 |2     |f       |7         |5         |4             |5             |timestamp|
|7 |3     |g       |8         |6         |8             |9             |timestamp|
|8 |3     |h       |9         |7         |9             |7             |timestamp|
|9 |3     |i       |1         |8         |7             |8             |timestamp|

问题答案:

第1季:FIRST_VALUE / LAST_VALUE

问题2:PARTITION BY(正如罗曼·佩卡(Roman Pekar)所建议的那样)

在这里查看

SELECT
  DISTINCT i.id AS id,
  i.userid AS userid,
  i.itemname AS itemname,
  COALESCE(LEAD(i.id)        OVER (ORDER BY i.created DESC)
          ,FIRST_VALUE(i.id) OVER (ORDER BY i.created DESC ROWS BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING)) AS nextitemid,
  COALESCE(LAG(i.id)         OVER (ORDER BY i.created DESC)
          ,LAST_VALUE(i.id)  OVER (ORDER BY i.created DESC ROWS BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING)) AS previtemid,
  COALESCE(LEAD(i.id)        OVER (PARTITION BY i.userid ORDER BY i.created DESC)
          ,FIRST_VALUE(i.id) OVER (PARTITION BY i.userid ORDER BY i.created DESC ROWS BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING)) AS nextuseritemid,
  COALESCE(LAG(i.id)         OVER (PARTITION BY i.userid ORDER BY i.created DESC)
          ,LAST_VALUE(i.id)  OVER (PARTITION BY i.userid ORDER BY i.created DESC ROWS BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING)) AS prevuseritemid,
  i.created AS created
FROM items i
  LEFT JOIN users u
  ON i.userid = u.id
ORDER BY i.created DESC;


 类似资料:
  • 我想不出如何将这个查询转换为delete-statment。 从购物车中选择DISTINCT carts.id,Shows.Date 内部连接tickets.cart=carts.id上的票证 内部连接actseats.ticket=tickets.id上的actseats 内部连接对actseats.showact=showacts.id显示作用 内部联接显示在shows.id=showacts

  • 问题内容: 我有一个表,其中包含许多ID和与每个ID相关联的许多日期,甚至还有一些没有日期的ID。对于每个ID和日期组合,我想选择ID,日期和也与该ID关联的下一个最大日期;如果不存在,则选择null作为下一个日期。 样品表: 所需的输出: 问题答案: SELECT mytable.id, mytable.date, ( SELECT MIN(mytablemin.date) FROM mytab

  • 问题内容: 有没有类似于.Net 和Java的属性。 问题答案: 使用List接口的方法获取对象。从那里,你可以使用,,,和方法来浏览列表。这是一个使用的非常简单的示例。 示例代码应打印“ A”。

  • 我非常努力地显示下一个&上一个按钮,不管它是否在我的wordpress主题上处于活动状态。我似乎想不出一个办法来让它工作。我正在尝试这样做:http://www.kinocreative.co.uk/hints-and-tips/wordpress-nextpreview-post-navigation-with-images-and-inactive-links/extracty but for

  • 问题内容: 因此,我有一个需要使用mysql_query()加载的SQL转储文件。不幸的是,不可能用它执行多个查询。 ->不能假定安装了 mysql命令行客户端 (mysql –help)-直接加载SQL文件 ->无法假定已安装 mysqli 扩展 下面的explode()无法使用,因为某些转储内容的值包含分号。 在不修改转储文件的情况下加载SQL的最佳方法是什么? 问题答案: 您有更多的问题案例

  • 问题 你需要计算相关日期范围例如“上一个月”,“下一个月”。 解决方案 添加或减去当月的数字,JavaScript 的日期构造函数会修复数学知识。 # these examples were written in GMT-6 # Note that these examples WILL work in January! now = new Date # => "Sun, 08 May 2011