如果我有一个关于返回附近咖啡馆的查询:
SELECT * FROM cafes c WHERE (
ST_DWithin(
ST_GeographyFromText(
'SRID=4326;POINT(' || c.longitude || ' ' || c.latitude || ')'
),
ST_GeographyFromText('SRID=4326;POINT(-76.000000 39.000000)'),
2000
)
)
Run Code Online (Sandbox Code Playgroud)
如何选择距离以及按距离排序?
有没有比这更有效的方法:
SELECT id,
ST_Distance(ST_GeographyFromText('SRID=4326;POINT(-76.000000 39.000000)'),
ST_GeographyFromText(
'SRID=4326;POINT(' || c.longitude || ' ' || c.latitude || ')')
) as distance
FROM cafes c
WHERE (
ST_DWithin(
ST_GeographyFromText(
'SRID=4326;POINT(' || c.longitude || ' ' || c.latitude || ')'
),
ST_GeographyFromText('SRID=4326;POINT(-76.000000 39.000000)'),
2000
)
) order by distance
Run Code Online (Sandbox Code Playgroud) 我知道IN
Postgres 中的语句不能保证返回行的顺序。例如,如果我这样做:
SELECT users.id FROM users WHERE users.id IN (13589, 16674, 13588)
Run Code Online (Sandbox Code Playgroud)
我可能会得到这样的结果:
16674
13588
13589
Run Code Online (Sandbox Code Playgroud)
但是,我希望返回的行尊重IN
列表中的顺序,所以我在网上找到的解决方案很少,例如:
SELECT users.id FROM users WHERE users.id IN (13589, 16674, 13588)
ORDER BY POSITION(id::text in '(13589, 16674, 13588)')
Run Code Online (Sandbox Code Playgroud)
或者
SELECT users.id FROM users WHERE users.id IN (13589, 16674, 13588)
ORDER BY id = 13589 desc,
id = 16674 desc,
id = 13588 desc;
Run Code Online (Sandbox Code Playgroud)
我想知道是否有更好的方法来做到这一点,或者更好但更有效?
我从 table 中得到了一堆 id messages
,我想更新 table activities
。这就是我想象我的查询会起作用的方式(因此您可以更好地了解我要完成的任务):
update activities
set activities.created_at = messages.created_at,
set activities.updated_at = messages.updated_at
from messages
where messages.id in (1,2,3)
activities.trackable_id in (1,2,3)
Run Code Online (Sandbox Code Playgroud)
在 中activities
,trackable_id
是messages
表的外键。所以我需要在活动表中为一些消息设置权限created_at
和updated_at
时间。
所以基本上activity
表格是表格的副本,messages
但只是另一种格式。
如何更新活动表中某些消息 ID 的 created_at 和 updated_at,但使用消息表中的数据(数据为 updated_at 和 created_at)?
我有从用户到地址表的一对一关系。一位用户可以拥有一个搜索地址和一个经过验证的地址。
我在地址表上有两个索引:
我正在尝试仅为某些用户获取地址,而那些状态不是manual_verification
.
这是我的查询:
SELECT users.id
FROM "users" INNER JOIN addresses
ON addresses.user_id = users.id
and addresses.type = 'VerifiedAddress'
WHERE ("users".deleted_at IS NULL)
AND (users.id in (11144,10569,21519,783,15671,21726,17787,11665,
19579,12226,1324,9413,5461,20981,12906)
and addresses.state != 'manual_verification')
Run Code Online (Sandbox Code Playgroud)
解释上面的查询:http : //explain.depesz.com/s/rTj
需要 37 毫秒。有时更多取决于用户数量。
我认为这是一个很好的查询,但是我们的团队需要对此进行调查,我正在寻找一些优化技巧。我的意思是我做了一个字段选择,user_id(地址)和状态(地址)上有一个索引。
还有什么我可以做/尝试的吗?
更新
我发现这个查询的工作速度要快得多:
SELECT "addresses"."user_id"
FROM "addresses"
WHERE "addresses"."type" IN ('VerifiedAddress')
AND (user_id in (9681,23824,23760,20098,962,14730,12294,9552,534,
553,5837,6768,6583,956,24179) and state != 'manual_verification')
Run Code Online (Sandbox Code Playgroud)
解释这个查询:http : //explain.depesz.com/s/nHrr
我有这个查询:
select (quarter_1 + quarter_2 + quarter_3 + quarter_4) as total
from budget where as_of_dt < to_date('2016-06-28', 'yyyy-MM-dd')
order by as_of_dt desc;
Run Code Online (Sandbox Code Playgroud)
它返回一堆数字,例如:
我的要求是始终捕获第一个数字,因此当我尝试这样做时:
select * from (
select (quarter_1 + quarter_2 + quarter_3 + quarter_4) as total
from budget where as_of_dt < to_date('2016-05-16', 'yyyy-MM-dd')
order by as_of_dt desc
) WHERE ROWNUM = 1
Run Code Online (Sandbox Code Playgroud)
我得到这个结果:
这就是为什么我对此感到困惑,为什么我得到的是第二行而不是第一行?我在这里做错了什么?
更新在第一次查询的结果中包含 as_of_dt:
postgresql ×4
gist-index ×1
index ×1
oracle ×1
oracle-11g ×1
order-by ×1
performance ×1
postgis ×1