Ren*_*ani 22 sql postgresql window
我想知道如何在SQL查询中检索结果,与下一行或上一行进行一些逻辑比较.我正在使用PostgreSQL.
示例
假设我的数据库中有一个包含两个属性(有序位置和随机数)的表,我想检索偶数之间的奇数.我怎样才能做到这一点?
真正的用法
我想找到两个具有NAME类别的单词之间的单词(而单词不是名称).订购由句子和位置提供.
编辑 我想知道PostgreSQL的Window函数是否是解决此类问题的最佳解决方案.我听说过他们,但从未使用过.
Ren*_*ani 43
这是我使用的解决方案WINDOW functions.我使用了lag和lead函数.两者都从与当前行偏移的行中的列返回值.lag返回并lead在偏移中接下来.
SELECT tokcat.text
FROM (
SELECT text, category, chartype, lag(category,1) OVER w as previousCategory, lead(category,1) OVER w as nextCategory
FROM token t, textBlockHasToken tb
WHERE tb.tokenId = t.id
WINDOW w AS (
PARTITION BY textBlockId, sentence
ORDER BY textBlockId, sentence, position
)
) tokcat
WHERE 'NAME' = ANY(previousCategory)
AND 'NAME' = ANY(nextCategory)
AND 'NAME' <> ANY(category)
Run Code Online (Sandbox Code Playgroud)
简化版:
SELECT text
FROM (
SELECT text
,category
,lag(category) OVER w as previous_cat
,lead(category) OVER w as next_cat
FROM token t
JOIN textblockhastoken tb ON tb.tokenid = t.id
WINDOW w AS (PARTITION BY textblockid, sentence ORDER BY position)
) tokcat
WHERE category <> 'NAME'
AND previous_cat = 'NAME'
AND next_cat = 'NAME';
Run Code Online (Sandbox Code Playgroud)
= ANY() 不需要,window函数返回单个值PARTITION BYORDER BY 在分区中应用您可以在以下地址找到最佳解决方案:
SQL Server 2012及更高版本的查询1:
SELECT
LAG(p.FirstName) OVER(ORDER BY p.BusinessEntityID) PreviousValue,
p.FirstName,
LEAD(p.FirstName) OVER(ORDER BY p.BusinessEntityID) NextValue
FROM Person.Person p
GO
Run Code Online (Sandbox Code Playgroud)
SQL Server 2005+及更高版本的查询2:
WITH CTE AS(
SELECT rownum = ROW_NUMBER() OVER(ORDER BY p.BusinessEntityID),
p.FirstName FROM Person.Person p
)
SELECT
prev.FirstName PreviousValue,
CTE.FirstName,
nex.FirstName NextValue
FROM CTE
LEFT JOIN CTE prev ON prev.rownum = CTE.rownum - 1
LEFT JOIN CTE nex ON nex.rownum = CTE.rownum + 1
GO
Run Code Online (Sandbox Code Playgroud)
这应该有效:
SELECT w1.word AS word_before, w.word, w2.word AS word_after
FROM word w
JOIN word w1 USING (sentence)
JOIN word w2 USING (sentence)
WHERE w.category <> 'name'
AND w1.pos = (w.pos - 1)
AND w1.category = 'name'
AND w2.pos = (w.pos + 1)
AND w2.category = 'name'
Run Code Online (Sandbox Code Playgroud)
IS NOT NULL回答您的附加问题:不,在这种情况下,窗口函数不是特别有用,自连接是这里的魔法词。
编辑:
我站纠正。Renato 使用窗口函数lag() 和 lead()演示了一个很酷的解决方案。
注意细微的差别:
pos -1缺少行,则行pos不符合条件。lag(),并lead()在运行行的相对位置所创造ORDER BY。在许多情况下(比如可能在手头的那个?)两个版本都会导致相同的结果。id 空间的间隙会有不同的结果。
| 归档时间: |
|
| 查看次数: |
70065 次 |
| 最近记录: |