获得多个聚合结果值的最佳或最有效方法是什么?
基本上,我有一个电子邮件应用程序,想要获取每种类型的文件夹(收件箱、已发送、已存档、已标记...)的所有邮件数量,如下定义。
这是我在一个存储过程调用中尝试做的事情的示例。(其中 [uid] 是用户 ID)
SELECT * FROM Message
Inbox WHERE [to] = [uid]
Unread WHERE [to] = [uid] and isread = 0
Flagged WHERE [to] = [uid] and isFlagged = 1
Drafts WHERE [to] = [uid] and isDraft = 1
Sent Messages WHERE [from] = [uid]
Archived Messages WHERE [to] = [uid] and isArchived = 1
Run Code Online (Sandbox Code Playgroud) 我有两个表:详细信息和这些详细信息的总计。
详细信息(缓慢的解决方案):
select
OrderId = r.OrderId
, TotalQty = SUM(r.Quantity)
, TotalGrossConsid = SUM(r.Price * r.Quantity)
from dbo.Order r
group by r.OrderId
Run Code Online (Sandbox Code Playgroud)
总计(快速解决方案):
select
t.OrderId
, t.TotalQty
, t.TotalGrossConsid
, t.IsValid
from dbo.OrderTotal t
Run Code Online (Sandbox Code Playgroud)
有时总数变得无效(某些作业必须重新计算更改的总数,但会延迟)。如您所知,第二个查询更快,有效总数的数量多于无效总数。因此,我正在寻找一个组合查询,该查询从第二个表 (totals) 返回有效总数,并使用第一个慢查询返回动态重新计算的总数。所以我的目标将实现:所有总数都是有效的,响应时间比完全重新计算要快。
这是我的尝试(混合解决方案):
with fast_static(OrderId, TotalQty, TotalGrossConsid, IsValid)
as
(
select
t.OrderId
, t.TotalQty
, t.TotalGrossConsid
, t.IsValid
from dbo.OrderTotal t
)
, slow_dynamic(OrderId, TotalQty, TotalGrossConsid)
(
select
OrderId = r.OrderId
, TotalQty = SUM(r.Quantity)
, TotalGrossConsid = SUM(r.Price …Run Code Online (Sandbox Code Playgroud) performance sql-server-2008 query aggregate materialized-view
Postgres 的 string_agg(expr, delimiter) 函数很棒。但我想要一个版本,它接受一个参数——要聚合的字段——并假设分隔符为 ', ' 因为这是我想要的 10 次中的 9 次。使用非聚合函数,我可以只需这样做:
create or replace function public.string_agg(text)
returns text
as $$
select string_agg($1, ', ');
$$ language sql
immutable;
Run Code Online (Sandbox Code Playgroud)
但由于 string_agg 是一个聚合函数,这不起作用。它抱怨我传递给它的字段需要在 GROUP BY 子句中,这告诉我查询引擎不知道我的包装器是一个聚合函数。
我查看了用户定义聚合的文档(http://www.postgresql.org/docs/9.1/static/xaggr.html 和http://www.postgresql.org/docs/9.1/static/sql-createaggregate .html ) 但我不清楚如何使用现有的 string_agg(text, text) 定义我的新 string_agg(text)。看来我必须从头开始定义我的新函数,这比我想承担的要复杂得多,而且我也不完全有信心我可以完美地反映内置 string_agg 的行为。
那么是否有一些技术可以创建一个我没有看到的简单包装器?或者我将不得不做更多的工作?
有了这个查询:
SELECT SUM(qty) AS sumQty,
cnetprodid
FROM quoteitem
WHERE ordered = 1
AND sageSOPOrderReturnLineID IS NOT NULL
AND LEN(LTRIM(RTRIM(cnetprodid))) > 0
AND cnetprodid LIKE 'S%'
AND price > 10
AND created > DATEADD(MONTH, -3, GETDATE())
GROUP BY cnetprodid
ORDER BY SUM(qty) DESC
Run Code Online (Sandbox Code Playgroud)
每个产品我得到一排,顶排有 294 个 assumQty和 'S10381902' 作为cnetprodid
输入此查询:
SELECT SUM(qty) AS sumQty,
p.ProdID,
p.CatID
FROM quoteitem
INNER JOIN cds_prod AS p
ON p.ProdID COLLATE Latin1_General_CI_AS = cnetprodid
INNER JOIN cds_atr AS a
ON a.ProdID COLLATE Latin1_General_CI_AS …Run Code Online (Sandbox Code Playgroud) 我有两张这样的表:
CREATE TABLE cmap5 (
name varchar(2000),
lexemes tsquery
);
Run Code Online (Sandbox Code Playgroud)
和
CREATE TABLE IF NOT EXISTS synonyms_all_gin_tsvcolumn (
cid int NOT NULL, -- REFERENCES pubchem_compounds_index(cid)
name varchar(2000) NOT NULL,
synonym varchar(2000) NOT NULL,
tsv_syns tsvector,
PRIMARY KEY (cid, name, synonym)
);
Run Code Online (Sandbox Code Playgroud)
我目前的查询是:
SELECT s.cid, s.synonym, c.name, ts_rank(s.tsv_syns,c.lexemes,16)
FROM synonyms_all_gin_tsvcolumn s, cmap5 c
WHERE c.lexemes @@ s.tsv_syns
Run Code Online (Sandbox Code Playgroud)
输出是:
cid | synonym | name (query) | rank
5474706 | 10-Methoxyharmalan | 10-methoxyharmalan | 0.0901673
1416 | (+/-)12,13-EODE | 12,13-EODE | 0.211562
5356421 …Run Code Online (Sandbox Code Playgroud) postgresql aggregate full-text-search group-by greatest-n-per-group
AVG()SQL 中的函数适用于特定的列数据。但在这里,我们要计算每行三个这样的列的平均值。在数学中,我们会做
AVG=(col1 + col2 + col3)/3
Run Code Online (Sandbox Code Playgroud)
同样:是否有任何查询要计算AVG(col1, col2, col3...)?
所以我有一个真正的休息日什么的,但对于我的生活,我无法弄清楚这一点。我想分tier1由total获得总数的百分比。我是这样想的:
(tier1 / total) as per
Run Code Online (Sandbox Code Playgroud)
但没有运气。我将这些 CAST 作为 int 并且仍然没有。我会得到一个错误并且查询不会执行,或者我会得到一个值 0。
这是我正在尝试使用的内容:
SELECT count(student_id) as total
,(SELECT count(fall_september_tier) FROM national_assessments.aimsweb WHERE general_outcome_measure = 'PSF' AND fall_september_tier = 1) as tier1
,(SELECT count(fall_september_tier) FROM national_assessments.aimsweb WHERE general_outcome_measure = 'PSF' AND fall_september_tier = 2) as tier2
,(SELECT count(fall_september_tier) FROM national_assessments.aimsweb WHERE general_outcome_measure = 'PSF' AND fall_september_tier = 3) as tier3
FROM national_assessments.aimsweb
WHERE general_outcome_measure = 'PSF' AND fall_september_tier IS NOT NULL
Run Code Online (Sandbox Code Playgroud)
我也有这个想法,但没有运气:
SELECT tier1,total, tier1/total as test …Run Code Online (Sandbox Code Playgroud) 我正在使用 Postgres,它强制执行 SELECT...GROUP BY 中的所有列必须出现在 GROUP BY 子句中或在聚合函数中使用的约束。
假设我正在为人们的汽车建模,我想算出一个人的姓名、牌照号码以及他们拥有的汽车数量。这是我作为SQL Fiddle 的示例。
我会有以下架构:
CREATE TABLE person(
id integer PRIMARY KEY,
name text
);
CREATE TABLE license(
person_id integer REFERENCES person(id),
expiry_date date
);
CREATE TABLE car(
owner_id integer REFERENCES person(id),
registration_number TEXT
);
Run Code Online (Sandbox Code Playgroud)
这是查询:
SELECT person.name, person.id, license.expiry_date, COUNT(car) FROM person
JOIN license ON license.person_id = person.id
JOIN car ON car.owner_id = person.id
WHERE person.name = 'Charles Bannerman'
GROUP BY person.id;
Run Code Online (Sandbox Code Playgroud)
我知道,因为我自己的业务逻辑,一个人只能有一个license,所以当我加入这个人的时候,即使是GROUP BY'd,我应该可以找到他们的license number。但是,因为它不是 GROUP …
我正在尝试编写一个查询,当连接表 B 中的列包含表 A 中单个匹配行的多个不同值时,该查询从表 A 中返回一行。(A -> B 是 1 -> 多关系。)我构建了在上下文中演示这一点的 SQL 小提琴:http : //sqlfiddle.com/#!6/83952/1
在这个小提琴中,表格的design列perf_ticket_type对于每个ticket_type具有相同的 都应该是相同的perf_id,但我试图只选择它没有的实例。因此,对于perf_id3,design我当前使用的查询返回了不止一个唯一值。
我想我的结果是两列performance的表只对perf_id3的基础上的多重价值design为perf_id所加入的表。
过去我一直对 GROUP BY 的理解感到沮丧,所以我不确定我是否可以在这里做一些不同的事情来获得我想要的结果。此刻,我想我可以选择什么我都在拨弄到一个临时表,然后做另一个选择上是有GROUP BY perf_id HAVING COUNT(*) > 1得到我想要的东西(按其中列包含在一个以上的记录相同的数据选择行)但这似乎是一个额外的步骤。
PostgreSQL 版本:我的本地安装是 11.3,下面的小提琴是 10.0。两者的行为相同。
我有一个页面架构,每个页面都有部分,每个部分可以有不同类型的内容。当我查询某个页面时,我希望在 JSON 文档中输出有关该页面的所有信息。
我将 CTE 用于json_agg()每个部分的各种内容。最后,我将各个部分连接起来json_object_agg(),将部分标题映射到部分内容。
问题: json_object_agg()当页面没有任何部分时抛出错误。我已经通过使用没有章节标题的常规来验证有罪json_agg()。确切的错误:
error: field name must not be null
Run Code Online (Sandbox Code Playgroud)
我想要的:无论如何都不是错误。我不想在接收方进行自定义错误处理。如果查询可以返回 JSONNull来代替json_object_agg()没有部分的情况,那就更好了,但这是可选的。(欢迎其他优雅的解决方案)
文档
可能文档不完整或者我遗漏了一些东西。仅供参考。
在聚合表达式上它说(强调我的):
大多数聚合函数都会忽略 null 输入,因此一个或多个表达式产生null 的行将被丢弃。除非另有说明,对于所有内置聚合,这可以 假定为 true 。
在聚合函数中,json_object_agg()没有评论不处理null:
将名称/值对聚合为 JSON 对象
摆弄错误的域参数。将域更改为其他选项可以使其正常工作。使用不存在的域也可以正常工作并返回 0 行。
询问
with secs as (
select p.page_id, p.domain, s.section_id as sid, s.title as title
from pages p
left …Run Code Online (Sandbox Code Playgroud) aggregate ×10
postgresql ×5
group-by ×3
sql-server ×2
t-sql ×2
count ×1
datatypes ×1
functions ×1
join ×1
json ×1
mysql ×1
performance ×1
query ×1