1

我很难将视图从 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:”是指定的回复格式,无论是否嵌套在主题字段中。

4

2 回答 2

2
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”。否则它们会自动小写。我的建议是专门使用小写标识符。

有根据的猜测

如果您实际上想要最早的created_atper行thread_id,并且您巧妙地保密,那么您的查询是不正确的,tSQL 或 PostgreSQL 类似。
你可以用DISTINCT ON它。

您可能也没有dbo在 Postgres 中命名的架构,这是来自 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
在每个 GROUP BY 组中选择第一行?

对于性能,表达式上的三元组 GIN索引 left(subject, 5)可能会有所帮助。更多信息:
PostgreSQL LIKE 查询性能变化

于 2013-07-26T22:32:37.397 回答
0

这是我自己来的最接近的……上面有更好的答案。

SELECT DISTINCT 
 thread_id
,first_value(message_id) OVER (Partition BY thread_id ORDER BY message_id) AS message_id
,first_value(parent_message_id) OVER (Partition BY thread_id ORDER BY parent_message_id) AS parent_message_id
,first_value(created_at) OVER (Partition BY thread_id ORDER BY created_at) AS initialResponse 
FROM bi_linear_thread
WHERE parent_message_id IS NOT NULL AND subject ~* '.*RE:.*'
GROUP BY message_id, thread_id, parent_message_id, created_at
ORDER BY thread_id desc
于 2013-07-29T16:07:38.217 回答