【问题标题】:SQL Find a result 1 field below the searchSQL 在搜索下方查找结果 1 字段
【发布时间】:2020-10-09 00:04:20
【问题描述】:

作为学习 SQL 项目的一部分,我已将字典下载为 .csv 文件并设置了一个表(其中包含 307,104 个单词的 1 列称为“单词”)。

我遇到了一些问题,它们是:

  • “数据库”后面是什么词
  • “数据库”后 2 个单词是什么单词
  • “数据库”前面是什么词
  • “数据库”前 2 个单词是什么单词

我找不到与此类查询相关的关键字,我们将不胜感激。

【问题讨论】:

  • 用您正在使用的数据库标记您的问题。

标签: sql select sql-order-by window-functions sql-limit


【解决方案1】:

您可以在公用表表达式中枚举带有row_number() 的单词(如果您的数据库支持这些功能),然后在外部查询中进行过滤:

with cte as (
    select word, row_number() over(order by word) rn
    from mytable 
)
select c.word
from cte c
where c.rn = (
    select c1.rn from cte c1 where c1.word = 'database'
) + 1

这给了你紧跟在“数据库”之后的词。您可以更改最终的+ 1 以获得其他结果(例如,要获得两个位置之前的单词,您可以使用- 2)。

另一个选项使用行限制查询。

获取下一个单词:

select word
from mytable
where word > 'database'
order by word
limit 1

单词后面两个位置:

select word
from mytable
where word > 'database'
order by word
limit 1, 1

前置词:

select word
from mytable
where word < 'database'
order by word desc
limit 1

单词前两个位置:

select word
from mytable
where word < 'database'
order by word desc
limit 1, 1

注意:行限制子句的语法因数据库而异。

【讨论】:

  • 您好,谢谢您,完美运行,之前没有使用 WITH 公用表表达式
【解决方案2】:

您可以使用LAG()(用于“数据库”之前的单词)和LEAD()(用于“数据库”之后的单词)等窗口函数:

select t.result 
from (
  select columnname, lag(columnname, 1) over (order by (select null)) result
  from words
) t
where t.columnname = 'Database'

columnname 更改为您的专栏名称。
此查询返回“数据库”之前的单词,如果将 1 更改为 2,您将获得“数据库”之前 2 行的单词。
根据您的数据库,您可以在 over 子句中省略 order by (select null)

【讨论】:

    【解决方案3】:

    如果要数据库后面的词:

    select word
    from dictionary
    where word > database
    order by word
    fetch first 1 row only;
    

    后面两个词:

    select word
    from dictionary
    where word > database
    order by word
    offset 1 fetch first 1 row only;
    

    “之前”的查询类似,但排序和比较方向相反。

    您可以开始使用窗口函数。例如,如果您想要从 2 before 到 2 after 的所有单词,您可以使用窗口计数:

    select word
    from (select d.*,
                 sum(case when word = 'database' then 1 else 0 end) over (order by word range between 2 preceding and 2 following) as cnt_database
         from dictionary d
        ) d
    where cnt_database > 0;
    

    但是,使用(word) 上的索引,第一种方法会更快。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2012-05-09
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-03-28
      • 2014-05-12
      • 1970-01-01
      • 2021-03-04
      相关资源
      最近更新 更多