我陷入了SQL子查询选择。现在,我有一个表产品:
id | name | description
----+-------+----------------------
6 | 123 | this is a +
| | girl.
7 | 124 | this is a +
| | girl.
8 | 125 | this is a +
| | girl.
9 | 126 | this is a +
| | girl.
10 | 127 | this is a +
| | girl.
11 | 127 | this is a +
| | girl. Isn't this?
12 | 345 | this is a cute slair
13 | ggg | this is a +
| | girl
14 | shout | this is a monster
15 | haha | they are cute
16 | 123 | this is cute
我想要做的是找到( 记录总数 和 前5条记录 )'1'
或'this'
列中包含name
或description
。
我能弄清楚的是如此丑陋:
SELECT *, (select count(id)
from (SELECT * from products
where description like any (array['%1%','%this%'])
or name like any (array['%1%','%this%'])
) as foo
) as total
from (SELECT * from products
where description like any (array['%1%','%this%'])
or name like any (array['%1%','%this%']))
) as fooo
limit 5;
答案 0 :(得分:1)
假设您使用的是postgresql 9.0+,可以使用CTE来实现此目的。 例如
WITH p AS (
SELECT *
FROM products
WHERE description LIKE ANY (ARRAY['%1%','%this%']) OR name LIKE ANY (ARRAY['%1%','%this%'])
)
SELECT *,
(select count(*) from p) as total
FROM p
ORDER BY id LIMIT 5;
答案 1 :(得分:1)
您可以使用聚合函数count()
作为窗口函数来计算同一查询级别的总计数:
SELECT id, name, description, count(*) OVER () AS total
FROM products p
WHERE description LIKE ANY ('{%1%,%this%}'::text[])
OR name LIKE ANY ('{%1%,%this%}'::text[])
ORDER BY id
LIMIT 5;
除了这些函数之外,任何内置或用户定义的聚合函数都可以用作窗口函数
这很有效,因为在窗口函数之后应用了LIMIT
。
我还使用了数组文字的替代语法。一个和另一个一样好。对于较长的阵列,这个较短。有时候需要一个明确的类型转换。我在这里假设text
。
在我的测试中,它比具有CTE的版本更简单,更快。
顺便说一下,这个带有正则表达式的WHERE
子句更短 - 但更慢:
WHERE description ~ '(1|this)'
OR name ~ '(1|this)'
还有一个测试:我发现原始版本(类似于你已经的版本)甚至 更快 :
SELECT id, name, description
, (SELECT count(*)
FROM products p
WHERE description LIKE ANY ('{%1%,%this%}'::text[])
OR name LIKE ANY ('{%1%,%this%}'::text[])
) AS total
FROM products p
WHERE description LIKE ANY ('{%1%,%this%}'::text[])
OR name LIKE ANY ('{%1%,%this%}'::text[])
ORDER BY id
LIMIT 5;