postgresql select 具有最小值的行
postgresql select row with minimum value
这是我在 PostgreSQL 中的查询:
SELECT
"axapta_calls".id,
"axapta_calls".call_time,
calls.calltime,
"calls"."id" as "call_id",
abs(extract(epoch from (axapta_calls.call_time::timestamp - calls.calltime::timestamp))) as ab
FROM
"axapta_calls"
inner join
"calls" (ON
axapta_calls.converted_outer_phone=calls.caller_phone
and abs(extract(epoch from (axapta_calls.call_time::timestamp - calls.calltime::timestamp)))<= 600 )
WHERE ("axapta_calls"."id" > 0)
GROUP BY "axapta_calls"."id", "calls"."id"
结果是:
如何只获得最小 "ab" 值的一行?
我将此查询更改为:
SELECT
distinct on (axapta_calls.id)
"axapta_calls".id,
"axapta_calls".call_time,
calls.calltime,
"calls"."id" as "call_id",
abs(extract(epoch from (axapta_calls.call_time::timestamp - calls.calltime::timestamp))) as ab
FROM
"axapta_calls"
inner join
"calls" ON
axapta_calls.converted_outer_phone=calls.caller_phone
and abs(extract(epoch from (axapta_calls.call_time::timestamp - calls.calltime::timestamp)))<= 600
WHERE ("axapta_calls"."id" > 0)
GROUP BY "axapta_calls"."id", "calls"."id"
但是得到第二行 ab = 347.783。我做错了什么?
您缺少 ORDER BY
子句。您应该首先按 id
排序,然后按 ab
列排序。然后,Postgres 将 return 为每个 id
对应于最低 ab
值的单个记录。
SELECT
distinct on (axapta_calls.id),
"axapta_calls".id,
"axapta_calls".call_time,
calls.calltime,
"calls"."id" as "call_id",
abs(extract(epoch from (axapta_calls.call_time::timestamp - calls.calltime::timestamp))) as ab
FROM
"axapta_calls"
inner join "calls"
ON axapta_calls.converted_outer_phone=calls.caller_phone and
abs(extract(epoch from (axapta_calls.call_time::timestamp - calls.calltime::timestamp)))<= 600 )
WHERE ("axapta_calls"."id" > 0)
ORDER BY
axapta_calls.id, 5;
您也可以使用分析功能:
select *
from
(SELECT
"axapta_calls".id,
"axapta_calls".call_time,
calls.calltime,
"calls"."id" as "call_id",
abs(extract(epoch from (axapta_calls.call_time::timestamp - calls.calltime::timestamp))) as ab,
rank() OVER (ORDER BY ab )rnk
FROM
"axapta_calls"
inner join
"calls" (ON
axapta_calls.converted_outer_phone=calls.caller_phone
and abs(extract(epoch from (axapta_calls.call_time::timestamp - calls.calltime::timestamp)))<= 600 )
WHERE ("axapta_calls"."id" > 0) )
where rnk=1
这是我在 PostgreSQL 中的查询:
SELECT
"axapta_calls".id,
"axapta_calls".call_time,
calls.calltime,
"calls"."id" as "call_id",
abs(extract(epoch from (axapta_calls.call_time::timestamp - calls.calltime::timestamp))) as ab
FROM
"axapta_calls"
inner join
"calls" (ON
axapta_calls.converted_outer_phone=calls.caller_phone
and abs(extract(epoch from (axapta_calls.call_time::timestamp - calls.calltime::timestamp)))<= 600 )
WHERE ("axapta_calls"."id" > 0)
GROUP BY "axapta_calls"."id", "calls"."id"
结果是:
如何只获得最小 "ab" 值的一行?
我将此查询更改为:
SELECT
distinct on (axapta_calls.id)
"axapta_calls".id,
"axapta_calls".call_time,
calls.calltime,
"calls"."id" as "call_id",
abs(extract(epoch from (axapta_calls.call_time::timestamp - calls.calltime::timestamp))) as ab
FROM
"axapta_calls"
inner join
"calls" ON
axapta_calls.converted_outer_phone=calls.caller_phone
and abs(extract(epoch from (axapta_calls.call_time::timestamp - calls.calltime::timestamp)))<= 600
WHERE ("axapta_calls"."id" > 0)
GROUP BY "axapta_calls"."id", "calls"."id"
但是得到第二行 ab = 347.783。我做错了什么?
您缺少 ORDER BY
子句。您应该首先按 id
排序,然后按 ab
列排序。然后,Postgres 将 return 为每个 id
对应于最低 ab
值的单个记录。
SELECT
distinct on (axapta_calls.id),
"axapta_calls".id,
"axapta_calls".call_time,
calls.calltime,
"calls"."id" as "call_id",
abs(extract(epoch from (axapta_calls.call_time::timestamp - calls.calltime::timestamp))) as ab
FROM
"axapta_calls"
inner join "calls"
ON axapta_calls.converted_outer_phone=calls.caller_phone and
abs(extract(epoch from (axapta_calls.call_time::timestamp - calls.calltime::timestamp)))<= 600 )
WHERE ("axapta_calls"."id" > 0)
ORDER BY
axapta_calls.id, 5;
您也可以使用分析功能:
select *
from
(SELECT
"axapta_calls".id,
"axapta_calls".call_time,
calls.calltime,
"calls"."id" as "call_id",
abs(extract(epoch from (axapta_calls.call_time::timestamp - calls.calltime::timestamp))) as ab,
rank() OVER (ORDER BY ab )rnk
FROM
"axapta_calls"
inner join
"calls" (ON
axapta_calls.converted_outer_phone=calls.caller_phone
and abs(extract(epoch from (axapta_calls.call_time::timestamp - calls.calltime::timestamp)))<= 600 )
WHERE ("axapta_calls"."id" > 0) )
where rnk=1