数组经常用来在一列里存多个值——比如标签、号码、角色或者偏好啥的。但怎么判断数组里有没有我们想要的值,或者说——是不是所有元素都满足某个条件?PostgreSQL给我们提供了很方便的工具:ANY、ALL和array_contains()。下面一个个来聊聊。
啥是ANY?
想象一下,你有个数组,里面列着一堆值,比如商品ID、电话号码或者兴趣列表。经常会遇到要查查数组里有没有某个特定值。这时候ANY操作符就派上用场了。它能帮你判断“我们要找的东西”是不是在数组里。
ANY的语法
SELECT *
FROM your_table
WHERE value = ANY(array_column);
这里:
array_column—— 就是我们要查的数组。value—— 就是你要在数组里找的那个值。
ANY的用法示例
比如我们有个students表,结构如下:
| id | name | hobbies |
|---|---|---|
| 1 | Otto | {阅读, 游泳, 国际象棋} |
| 2 | Eva | {音乐, 阅读, 运动} |
| 3 | Alex | {绘画, 音乐} |
| 4 | Maria | {国际象棋, 足球} |
我们想找兴趣里有游泳的学生。查询如下:
SELECT *
FROM students
WHERE '游泳' = ANY(hobbies);
结果:
| id | name | hobbies |
|---|---|---|
| 1 | Otto | {阅读, 游泳, 国际象棋} |
简单说,ANY就是在问:“这个数组里有这个值吗?”
信则用,查到底!用ALL
现在想象下反过来的场景:你要确保数组里的所有元素都满足某个规则。PostgreSQL有ALL操作符。它能帮你判断数组里的所有元素是不是都等于某个值、是不是都大于某个数,或者满足别的逻辑条件。
ALL的语法
SELECT *
FROM your_table
WHERE value < ALL(array_column);
这里:
array_column—— 就是我们要查的数组。value < ALL(...)意思是所有数组元素都要比这个值大。
回到我们的students表。假如我们想找所有兴趣都以“阅”开头的学生。查询:
SELECT *
FROM students
WHERE '阅读' = ALL(hobbies);
结果是空的,因为没有人所有兴趣都是“阅读”。为了让例子更直观(也能查出结果),我们换成数字数据。
比如有个orders表:
| id | customer | prices |
|---|---|---|
| 1 | Otto | {100, 200, 300} |
| 2 | Eva | {50, 60, 70} |
| 3 | Alex | {500, 600, 700} |
找出所有每个价格都低于400的订单:
SELECT *
FROM orders
WHERE 400 > ALL(prices);
结果:
| id | customer | prices |
|---|---|---|
| 1 | Otto | {100, 200, 300} |
| 2 | Eva | {50, 60, 70} |
按数组内容过滤行
我们讲了查数组的基础函数和操作符,那实际用起来咋样?来看几个例子。
例1:找兴趣里至少有一个是音乐的学生
原始表:
| id | name | hobbies |
|---|---|---|
| 1 | Otto | {阅读, 音乐, 跑步} |
| 2 | Eva | {绘画, 游泳} |
| 3 | Maria | {音乐, 拳击} |
| 4 | Alex | {足球, 拳击, 桌游} |
SELECT *
FROM students
WHERE '音乐' = ANY(hobbies);
结果:
| id | name | hobbies |
|---|---|---|
| 1 | Otto | {阅读, 音乐, 跑步} |
| 3 | Maria | {音乐, 拳击} |
例2:找所有价格都大于100的订单
原始表orders:
| id | customer | prices |
|---|---|---|
| 1 | Otto | {150, 200, 300} |
| 2 | Eva | {50, 120, 130} |
| 3 | Maria | {200, 250, 100} |
| 4 | Alex | {110, 115, 120} |
SELECT *
FROM orders
WHERE 100 < ALL(prices);
结果:
| id | customer | prices |
|---|---|---|
| 1 | Otto | {150, 200, 300} |
| 4 | Alex | {110, 115, 120} |
常见错误和怎么避免
用数组查数据的时候,有几个坑要注意。
错误:ANY或ALL用错了。 比如你把操作符搞反了,结果就会很奇怪。
-- 错误示例:
SELECT *
FROM students
WHERE hobbies = ANY('阅读');
这里的问题是hobbies是数组,'阅读'是字符串。应该用数组去ANY,不是反过来。
错误:数组下标从1开始,不是0。 如果你用别的函数处理数组或者手动取元素,记得PostgreSQL的数组下标是从1开始的。
错误:没加索引。 如果你经常用ANY、ALL查数组,记得加索引,这样查询会快很多。
GO TO FULL VERSION