我需要将这两个查询的结果放在一个具有以下结构的返回中:
"date", avg(selic."Taxa"), avg(titulos."puVenda")
表格的部分结构:
selic
"dtFechamento" date,
"pTaxa" real
titulos
"dtTitulo" date,
"puVenda" real,
"nomeTitulo" character(30)
查询表selic
:
select to_char("dtFechamento", 'YYYY-MM') as data, avg("pTaxa")
from "selic"
group by data
order by data
查询表titulos
:
select to_char("dtTitulo", 'YYYY-MM') as data, avg("puVenda")
from "titulos"
where "nomeTitulo" = 'LFT010321'
group by data
order by data
我尝试了一个子查询,但它返回了彼此相邻的字段,无法集合。
select *
from (select to_char("dtFechamento", 'YYYY-MM') as data, avg("pTaxa")
from "selic"
group by data
order by data) as selic,
(select to_char("dtTitulo", 'YYYY-MM') as data, avg("puVenda")
from "titulos"
where "nomeTitulo" = 'LFT010321'
group by data
order by data) as LFT010321;
答案 0 :(得分:1)
假设您希望每月返回一行,其中两个查询中的任何一个返回一行。并使用NULL填充其他查询中的缺失值。
SELECT to_char(mon, 'YYYY-MM') AS data, s.avg_taxa, t.avg_venda
FROM (
SELECT date_trunc('month', "dtFechamento") AS mon, avg("pTaxa") AS avg_taxa
FROM selic
GROUP BY 1
) s
FULL JOIN (
SELECT date_trunc('month', "dtTitulo") AS mon, avg("puVenda") AS avg_venda
FROM titulos
WHERE "nomeTitulo" = 'LFT010321'
GROUP BY 1
) t USING (mon)
ORDER BY mon;
在聚合之后加入比以前更快(加入操作次数更少)。
GROUP BY
JOIN
,ORDER
和timestamp
text
值比to_char()
再现更快。通常也更清晰,更不容易出错(尽管在这种特殊情况下文本是明确的)。这就是为什么我在较低级别使用date_trunc()
而不是function TForm3.CreateVHDX(const AFilePath: string; const ASize: ULONG; const AType: integer; out AReturn: DWORD): Boolean;
var
params: TCreateVirtualDiskParameters;
mask: TVIRTUAL_DISK_ACCESS_MASK;
vst: TVirtualStorageType;
hvhd: THandle;
begin
hVhd := INVALID_HANDLE_VALUE;
// vst.DeviceId := VIRTUAL_STORAGE_TYPE_DEVICE_VHDX;
vst.DeviceId := VIRTUAL_STORAGE_TYPE_DEVICE_UNKNOWN;
// vst.VendorId := VIRTUAL_STORAGE_TYPE_VENDOR_MICROSOFT ;
vst.VendorId := VIRTUAL_STORAGE_TYPE_VENDOR_UNKNOWN;
params.Version:= CREATE_VIRTUAL_DISK_VERSION_2;
params.Version2.UniqueId := TGUID.Empty;
params.Version2.MaximumSize:= ASize * 1024 * 1024;
params.Version2.BlockSizeInBytes := CREATE_VIRTUAL_DISK_PARAMETERS_DEFAULT_BLOCK_SIZE; //0
params.Version2.SectorSizeInBytes := $200;
params.Version2.PhysicalSectorSize := $200;
params.Version2.ParentPath := nil;
// params.Version2.OpenFlags := OPEN_VIRTUAL_DISK_FLAG_NONE;
params.Version2.ResiliencyGuid := TGUID.Empty;
// params.Version2.ParentVirtualStorageType := ;
mask := VIRTUAL_DISK_ACCESS_NONE;
if AType = 0 then //dynamic
begin
AReturn := CreateVirtualDisk(
@vst,
PWideChar(AFilePath),
mask,
nil,
CREATE_VIRTUAL_DISK_FLAG_NONE,
0,
@params,
nil,
hvhd);
Result := AReturn = ERROR_SUCCESS;
end;
if AType = 1 then //fixed
begin
AReturn := CreateVirtualDisk(
@vst,
PWideChar(AFilePath),
mask,
nil,
CREATE_VIRTUAL_DISK_FLAG_FULL_PHYSICAL_ALLOCATION,
0,
@params,
nil,
hvhd);
Result := AReturn = ERROR_SUCCESS;
end;
if hvhd <> INVALID_HANDLE_VALUE then
CloseHandle( hvhd )
end;
的原因。
如果月份的格式不重要,您只需返回时间戳值即可。否则,您可以在完成处理后以任何方式格式化。
类似案例有更多解释:
答案 1 :(得分:1)
这应该得到你所需要的。内部“PQ”(PreQuery)在每个可能的日期之间进行联合,但也添加了一个标志列来标识与之关联的平均值。每个部分按日期分组。所以现在,外部查询AT MOST在给定日期有2条记录......一条是税,另一条是文达。因此,现在您不需要任何完整的外部联接,也不需要构建一些动态日历数据,以获取所有可能日期的详细信息。
因此,可能只有税收平均值或Venda平均值或两者。
SELECT
PQ.Data,
SUM( CASE when PQ.SumType = 'T' then PQ.TypeAvg else 0 end ) as AvgTax,
SUM( CASE when PQ.SumType = 'V' then PQ.TypeAvg else 0 end ) as AvgVenda
from
( select
to_char( dtFechamento, 'YYYY-MM') as data,
'T' as sumtype,
avg( pTaxa ) as TypeAvg
from
selic
group by
to_char( dtFechamento, 'YYYY-MM') as data
UNION ALL
select
to_char( dtTitulo, 'YYYY-MM') as data,
'V' as sumType,
avg( puVenda ) as TypeAvg
from
titulos
where
nomeTitulo = 'LFT010321'
group by
to_char( dtTitulo, 'YYYY-MM') ) PQ
group by
PQ.Data
order by
PQ.Data