在PostgreSQL中,我想根据某些条件选择一行,但是如果没有行与该条件匹配,则我想返回第一行。该表实际上包含一个序数列,因此该任务应该更容易(第一行是序数为0的那一行)。例如:
SELECT street, zip, city
FROM address
WHERE street LIKE 'Test%' OR ord = 0
LIMIT 1;
但是在这种情况下,无法保证匹配记录的顺序,因此我无法对其进行排序。使用单个SELECT
语句执行此操作的方式是什么?
我想根据某些条件选择一行,但是如果没有行与该条件匹配,我想返回第一行
你实际上并不需要一个WHERE
条款 都 :
SELECT street, zip, city
FROM address
ORDER BY street !~~ 'Test%', ord
LIMIT 1;
!~~
只是Postgres运算符的NOT LIKE
。您可以使用任何一个。请注意,通过反转逻辑(NOT LIKE
而不是LIKE
),我们现在可以使用默认的ASC
排序顺序和NULL最后排序,这可能很重要。继续阅读。
这更短(但不一定更快)。它也与@Gordon当前接受的答案稍有不同(更可靠)。
在 按boolean
表达式排序时,您必须了解其工作方式:
当前接受的答案使用ORDER BY <boolean expression> DESC
,它将首先对NULL进行排序。在这种情况下,通常应添加NULLS LAST
:
如果street
定义NOT NULL
这显然是不相关的,但是这并 没有 在这个问题被定义。( 始终
提供表定义。)当前接受的答案通过在WHERE
子句中排除NULL值来避免此问题。
其他一些RDBMS(MySQL,Oracle等)没有boolean
Postgres之类的适当类型,因此我们经常看到来自那些产品的人的错误建议。
您当前的查询(以及目前公认的答案), 需要 的WHERE
条款-或者至少NULLS LAST
。对于不同的表达,ORDER BY
两者都不是必需的。
更重要的 是,如果多行具有匹配项street
(这是可以预期的),则返回的行将是任意的,并且可能在调用之间发生变化-
通常是不希望有的结果。该查询选择ord
要打破平局的关系最小的行,并产生稳定的结果。
这种形式也更加灵活,因为它不依赖于带有的行的存在ord = 0
。取而代之的ord
是,选择最小的行。
(并且仍然正确。)对于大表,以下索引可以从根本上提高此查询的性能:
CREATE INDEX address_street_pattern_ops_idx ON address(street text_pattern_ops);
详细说明:
根据未定义的详细信息,可能需要向索引中添加更多列。
使用此索引的最快查询:
(
SELECT street, zip, city
FROM address
WHERE street LIKE 'Test%'
ORDER BY ord -- or something else?
-- LIMIT 1 -- you *could* add LIMIT 1 in each leg
)
UNION ALL
(
SELECT street, zip, city
FROM address
ORDER BY ord
-- LIMIT 1 -- .. but that's not improving anything in *this* case
)
LIMIT 1
顺便说一句,这是一个 单一的 声明。
这比较冗长,但允许使用更简单的查询计划。如果第一个产生足够多的行(在我们的示例中为1)SELECT
,UNION ALL
则永远不会执行第二个SELECT
。如果使用进行测试EXPLAIN ANALYZE
,则会(never executed)
在查询计划中看到。
细节:
UNION ALL
回应戈登的评论。每个文档:
除非括号中另有说明,否则
UNION
同一SELECT
语句中的多个运算符 从左到右 求值 。
大胆强调我的。一旦找到足够的行
,LIMIT
并使Postgres停止评估。这就是为什么您(never executed)
在的输出中看到的原因EXPLAIN ANALYZE
。
如果ORDER BY
在最终之前添加外部,LIMIT
则无法进行优化。然后,必须收集 所有 行以查看可能首先排序的行。
我有两个表客户和订单,下面是结构。 表-客户 ID customer_name 表-订单 ID order_id customer_id customers表包含customers记录,orders表包含客户下的订单, orders表中的customer_id链接到customers表的id字段。 现在一个客户可以有零或一个或多个订单,我想要得到客户下的最后一个订单只。 当我运行以下查询(一个简单
我有两张桌子: Product\u表 Productbreak\u表 我的目标是只获取不在productbreak_table的和日期之间的产品 结果应该是:
问题内容: 我正在尝试匹配模式: 以下仅匹配第一次出现的情况: 结果是: 但是,[使用pythex似乎可以正常工作](http://pythex.org/?regex=%3C–(%5B%5Cw%5Cs%5D%2B)–%3E(%5B%5Cs%5CS%5D*%3F)(%3F%3D%5Cn%3C–%7C%24)&test_string=%3C–%20Option%201%20–%3E%0ANice%20
问题内容: 假设以下单词顺序 我想做的是将文本从BLA提取到LOOK,但是最接近外观的BLA。即我想得到 我应该如何使用正则表达式呢?我得到了一个可行的解决方案,但是效率极低。 有没有更好,更高效的方法来实现此模式的匹配? 我想做的是:我想匹配BLA,然后向前进行前瞻,直到使用LOOK进行正向前进或使用BLA进行负向前进。但是我不知道将其放入正则表达式中的方法。 作为引擎,我在python中使用r
我在SQL Server2012中创建了以下存储过程... 它将显示类似于下面的输出... 我想让它做的是显示前几周的票数(今天和前6天),即使其中一些天没有门票进入。对他们来说只会显示0。因此,我的输出将看起来包含周四、周五、周六、周日、周一、周二、周三。
问题内容: 是否有任何Django函数可以让我从数据库中获取对象,如果没有匹配项,则为None? 现在我正在使用类似: 但这还不是很清楚,到处都是混乱的。 问题答案: 在Django 1.6中,你可以使用Queryset方法。它返回查询集匹配的第一个对象,如果没有匹配的对象,则返回None。 用法: