我很难将 View 从 T-SQL 转换为 Postgresql,因为它与聚合函数相关。
这是我的原始 SQL 查询:
SELECT TOP (100) PERCENT
thread_id,
MIN(message_id) AS message_id,
MIN(parent_message_id) AS parent_message_id,
MIN(created_at) AS initialResponse
FROM
dbo.bi_linear_thread
WHERE
LEFT([subject], 5) LIKE '%RE:%' AND parent_message_id IS NOT NULL
GROUP BY
thread_id
ORDER BY
thread_id
我尝试使用以下窗口函数:
first_value(message_id) OVER (Partition BY message_id ORDER BY messageid)
但继续得到不正确的返回。
想法?
编辑更多上下文
-- 在提供答案之后。希望这对其他人有帮助。
需要读取组中的第一行,该组排除了线程层次结构顺序中的第一条记录以回复。
thread_id
代表线程。
message_id
表示任何消息类型,无论是回复消息还是原始消息。 parent_message_id
表示线程中的原始消息。
“RE:”是一种指定的回复格式,无论是否嵌套在主题字段中。
最佳答案
SELECT thread_id
,MIN(message_id) AS message_id
,MIN(parent_message_id) AS parent_message_id
,MIN(created_at) AS initialResponse
FROM dbo.bi_linear_thread
WHERE left(subject, 5) LIKE '%RE:%'
AND parent_message_id IS NOT NULL
GROUP BY thread_id
ORDER BY thread_id;
除了从 [subject]
中删除非法括号并删除 TOP (100) PERCENT
外,这只是噪音,查询应该有效。
对于不区分大小写的模式匹配,您可能需要 ILIKE
而不是 LIKE
。
left()
是在 Postgres 9.1 中引入的。
如果您需要 CaMeL 大小写标识符,您需要用双引号引起来:“initialResponse”。否则它们会自动小写。我的建议是只使用小写标识符。
有根据的猜测
如果您确实想要每个 thread_id
具有最早 created_at
的行,您狡猾地保密了,您的查询是 不正确,tSQL 或 PostgreSQL 类似。
您可以为此使用 DISTINCT ON
。
您可能在 Postgres 中也没有名为 dbo
的模式,那是 SQL Server 的产物,所以我也删除了它。
如上所述,我使用 ILIKE
。
SELECT DISTINCT ON (thread_id)
thread_id, message_id, parent_message_id, created_at AS initial_response
FROM bi_linear_thread
WHERE left(subject, 5) ILIKE '%RE:%'
AND parent_message_id IS NOT NULL
ORDER BY thread_id, created_at;
关于DISTINCT ON
的信息:
Select first row in each GROUP BY group?
对于性能,三元组 GIN index on the expression left(subject, 5)
可能会有很大帮助。更多信息:
PostgreSQL LIKE query performance variations
关于sql - 如何将 TSQL 聚合函数转换为 Postgresql,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/17891933/