问题描述
我有以下postgreSQL查询(用户及其通过用户ID链接的消息的简单示例):
SELECT users.id,COUNT(messages.id) as "user_messages",COUNT(messages.id) FILTER (WHERE messages.status='sent') as "sent_messages"
FROM users
LEFT JOIN messages ON messages.user_id=users.id
GROUP BY users.id;
此查询在psql中运行良好,但是我不知道如何使用Typeorm's querybuilder在代码中添加FILTER
语句,文档并没有多大帮助。
目前,我的方法是:
queryBuilder.select('users.id','user_id')
.addSelect('COUNT(messages.id)','user_messages')
.addSelect('COUNT(messages.id)','sent_messages') // <- Add magic filter here?
.from('users','users')
.leftJoin('messages','messages','users.id = messages.users_id')
.groupBy('users.id')
我试图尽可能避免在每个选择中都使用子查询,因为第一个代码中的FILTER
方法似乎更简单。
解决方法
其中一个或多个应该起作用:
.addSelect('COUNT(messages.id) FILTER (WHERE messages.status = 'sent')','user_messages')
.addSelect('COUNT( (messages.status = 'sent')::int )','user_messages')
.addSelect('SUM(CASE WHEN messages.status = 'sent' THEN 1 ELSE 0 END)','user_messages')
,
我通过将整个过滤器添加到选择字符串中找到了可行的解决方法:
queryBuilder.select('users.id','user_id')
.addSelect('COUNT(messages.id)','user_messages')
.addSelect(`COUNT(messages.id) FILTER (WHERE messages.status='sent')`,'sent_messages')
.from('users','users')
.leftJoin('messages','messages','users.id = messages.users_id')
.groupBy('users.id')
这远非理想,因为整个过滤器都是作为字符串注入的,并且我不能使用TypeORM的任何参数实用程序。
我不确定是否有更好的解决方案。