仅选择部分结果,但获得总行数 [英] Select only partial result but get total number of rows

查看:40
本文介绍了仅选择部分结果,但获得总行数的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我在选择SQL子查询时陷入困境.现在,我有一个餐桌产品:

I got stuck on SQL subquery selection. Right now, I have a table products:

 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条记录 ),其中在 name description 列中包含'1''this'.

What I want to do is to find ( the total number of records and the first 5 records ) which contains '1' or 'this' in either name or description columns.

我能弄清楚的是多么丑陋:

What I can figure out is so ugly:

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;

推荐答案

您可以使用聚合函数 count()作为窗口函数来计算相同查询级别下的总数:

You can use the aggregate function count() as window function to compute the total count in the same query level:

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;

引用窗口功能手册:

除了这些功能之外,任何内置或用户定义的聚合函数都可以用作窗口函数

In addition to these functions, any built-in or user-defined aggregate function can be used as a window function

之所以可行,是因为在窗口功能之后 应用了 LIMIT .

This works, because LIMIT is applied after window functions.

我还对数组文字使用了另一种语法.一个和另一个一样好.对于较长的阵列,此长度较短.有时需要显式的类型转换.我在这里假设 text .

I also use an alternative syntax for array literals. One is as good as the other. This one is shorter for longer arrays. And sometimes an explicit type cast is needed. I am assuming text here.

它比测试中带有CTE的版本更简单,也更快一些.

It is simpler and a bit faster than the version with a CTE in my test.

顺便说一句,此带有正则表达式的 WHERE 子句较短-但较慢:

BTW, this WHERE clause with a regular expression is shorter - but slower:

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;

这篇关于仅选择部分结果,但获得总行数的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆