SQL 查询根据同一表中的另一行检索一行
我有一个表 statuses
,其中包含 id
、name
和 parent_id
列。
我想检索 parent_id = 9
的行。
如果没有这样的行,我想获取 id = 9 的行。
我可以通过单个查询得到这个吗?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(5)
您可以选择这两行,将
parent_id
匹配项排序在顶部,然后抓取顶行:如果
id
不是主键,您可以尝试union< /code> 其中仅当前半部分为空时才执行后半部分:
You could select both rows, order the
parent_id
matches on top, and grab the top row:If
id
is not a primary key, you could try aunion
where the second half is only executed if the first half is empty:@Andomar 的任何一个答案都可以。请务必使用 EXPLAIN ANALYZE 来找出哪一个是一旦你的表被填充,实际上会更快。事实上,如果您可以根据一些 解释分析。
Either of @Andomar's answers will work. Just be sure to use EXPLAIN ANALYZE to figure out which one is actually faster once you have your table populated. In fact, it would be nice if you could update your post with the results of which was faster based on a few EXPLAIN ANALYZE's.
更简单、更快:
如果没有任何 ID 存在,则此查询将返回一行
statuses
类型的行,其中填充有NULL
值,而到目前为止,此处的其他解决方案返回 no行。因为这就是当你打电话时会发生的事情从 NULL::statuses 中选择 *
。说明
COALESCE
本身无法对行
进行操作,代替变量的子查询预计仅返回一列。如果你尝试:你会得到
但是,对于 PostgreSQL 中的每个表,都存在同名的复合类型。您可以让子查询以复合类型返回整行,然后扩展类型。这就是查询的作用。
我使用 PostgreSQL 9.1.4 中类似的包含 70k 行的真实表运行了一个快速基准测试,两个唯一 ID 列均已索引。我测试了所有三种情况:
parent_id
存在,id
存在,不存在。此查询比此处的其他解决方案稍快。我还尝试了 @Parkyprg 的错误答案的固定等效项以及 @Endy 和 @Andomar 发布内容的简化版本:.. 在没有索引的表上可能会更快。
Simpler, faster:
If none of the IDs exist, this query returns a row of type
statuses
filled withNULL
values, while the other solutions here so far return no row. Because that's what happens when you callSELECT * FROM NULL::statuses
.Explanation
COALESCE
cannot operate onrows
per se, a sub-query in place of a variable is expected to return one column only. If you try:You get
However, for every table in PostgreSQL a composite type of the same name exists. You can have the subqueries return the whole row as composite type and expand the type afterwards. That's what the query does.
I ran a quick benchmark with a similar real life table of 70k rows in PostgreSQL 9.1.4, both unique ID columns indexed. I tested all three cases:
parent_id
exists,id
exists, none exists. This query is slightly faster than other solution here. I also tried a fixed equivalent of @Parkyprg's incorrect answer and a simplified version of what @Endy and @Andomar posted:.. which could be faster on tables without indexes.