0

我被困在 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'在任一namedescription中。

我能想到的太丑了:

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;
4

2 回答 2

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;
于 2013-07-18T22:05:08.533 回答
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;
于 2013-07-19T01:58:32.657 回答