我需要在postgresql数据库的单个SQL查询中返回多个值。这是我到目前为止的查询:
SELECT AVG("percent"), MIN("percent"), MAX("percent"), AVG("profit"), MIN("profit"), MAX("profit")
FROM public.log_analyticss
WHERE "buyPlatform" = 'platA' AND
"date" >= '1526356073.6126819'
数据
date sellPlatform profit percent
---------- ------------ ---------- ----------
1526356073.61 platA 0 10.1
1526356073.62 platA 22 11
1526356073.63 platA 3 7
1526356073.64 platA 1 8
1526356073.65 platA 11 9
1526356073.66 platA 12 10
1526356073.67 platA 13 15
期望的结果
date sellPlatform profit percent
---------- ------------ ---------- ----------
1526356073.61 platA 0 10.1 //MIN Profit
1526356073.62 platA 22 11 //MAX Profit
1526356073.63 platA 3 7 //MIN Perc
1526356073.67 platA 13 15 //MAX Perc
//然后以某种方式我希望它返回AVG,如果这是可能的。否则,我不介意运行另一个查询来执行此操作。
问题是我不想要MIN和MAX值。我想要从中获取MIN和MAX值的整行数据。
我知道我要求AVG和MIN / MAX值,它将以两种不同的格式返回数据。我知道这可能是不可能的。但任何有关如何最有效地做到这一点的帮助将是非常有帮助的。
现在我只是将整个数据集拉入我的代码并计算我的代码中的平均值,最小值和最大值,我知道这非常糟糕且非常慢。该表有大约800万行,我抓取的数据集大约是9000行,所以它现在的方式非常慢。
答案 0 :(得分:1)
检索与最小值/最大值关联的行的最有效方法通常不涉及MIN()
/ MAX()
聚合;相反,您只需在查询中附加ORDER BY
,然后添加LIMIT 1
即可获取第一条记录。
这意味着您需要四个SELECT
语句,其中包含四种不同的排序,但您可以将昂贵的部分(从log_analyticss
获取)分解为temp table或{{3} },例如:
WITH Data AS (
SELECT *
FROM public.log_analyticss
WHERE "buyPlatform" = 'platA' AND
"date" >= '1526356073.6126819'
)
(SELECT 'Min percent', * FROM Data ORDER BY "percent" ASC LIMIT 1)
UNION ALL
(SELECT 'Max percent', * FROM Data ORDER BY "percent" DESC LIMIT 1)
UNION ALL
(SELECT 'Min profit', * FROM Data ORDER BY "profit" ASC LIMIT 1)
UNION ALL
(SELECT 'Max profit', * FROM Data ORDER BY "profit" DESC LIMIT 1)
在您的情况下,临时表可能比CTE更好,因为您可以重新使用它来计算平均值。
请注意,如果其中一个最大/最小值由两个不同的行共享,则此查询将仅返回其中一个。所选行是随机有效选择的,但您可以将更多字段附加到ORDER BY
子句以作为打破平局。
如果在这种情况下你真的想要两个记录,你需要更像Auston或Radim的答案,即首先计算聚合,然后再加入profit
和percent
的数据列。您仍然可以在此处使用临时表/ CTE,以避免多次点击log_analyticss
。
答案 1 :(得分:0)
我认为最好的方法是通过两个查询: 第一个检索指标,就像你所做的那样; 第二个查询检索样本寄存器。
或者您可以尝试运行临时表(在结束会话后自动删除):
CREATE TEMP TABLE statistics AS
SELECT AVG(percent) as perc_avg, MIN(percent) as perc_avg, MAX(percent) as perc_max, AVG(profit) as pro_avg, MIN(profit) as pro_min, MAX(profit) as pro_max
FROM public.log_analyticss
WHERE buyPlatform = 'platA' AND
sellPlatform = 'platB' AND
productId = '183948' AND
date >= '1526356073.6126819'
;
SELECT date, sellPlatform, profit, percent
FROM public.log_analyticss a join statistics s
on (a.profit = s.pro_max or a.profit = s.pro_min or
a.percent = s.perc_max or a.percent = s.perc_min)
WHERE buyPlatform = 'platA' AND
sellPlatform = 'platB' AND
productId = '183948' AND
date >= '1526356073.6126819';
对临时表的引用: http://www.postgresql.org/docs/9.2/static/sql-createtable.html
答案 2 :(得分:0)
你需要这些内容:
SELECT a.*
FROM public.log_analyticss a
JOIN
(
SELECT
MIN("percent") min_percent,
MAX("percent") max_percent,
MIN("profit") min_profit,
MAX("profit") max_profit
FROM public.log_analyticss
) t ON a.date = t.date AND
a.sellPlatform = t.sellPlatform AND
(a.profit = minprofit OR
a.profit = maxprofit OR
a.percent = minpercent OR
a.percent = maxpercent)