fix averages in aggregation jobs
All checks were successful
continuous-integration/drone/push Build is passing
All checks were successful
continuous-integration/drone/push Build is passing
This commit is contained in:
@@ -28,6 +28,12 @@ Run `templ generate -path ./components` to generate code based on template files
|
|||||||
## Documentation
|
## Documentation
|
||||||
Run `swag init --exclude "pkg.mod,pkg.build,pkg.tools" -o server/router/docs`
|
Run `swag init --exclude "pkg.mod,pkg.build,pkg.tools" -o server/router/docs`
|
||||||
|
|
||||||
|
#### Snapshots and Reports
|
||||||
|
- Hourly snapshots capture inventory per vCenter (concurrency via `hourly_snapshot_concurrency`).
|
||||||
|
- Daily summaries aggregate the hourly snapshots for the day; monthly summaries aggregate daily summaries for the month.
|
||||||
|
- Snapshots are registered in `snapshot_registry` so regeneration via `/api/snapshots/aggregate` can locate the correct tables (fallback scanning is also supported).
|
||||||
|
- Reports (XLSX with totals/charts) are generated automatically after hourly, daily, and monthly jobs and written to a reports directory.
|
||||||
|
|
||||||
#### Settings File
|
#### Settings File
|
||||||
Configuration now lives in the YAML settings file. By default the service reads
|
Configuration now lives in the YAML settings file. By default the service reads
|
||||||
`/etc/dtms/vctp.yml`, or you can override it with the `-settings` flag.
|
`/etc/dtms/vctp.yml`, or you can override it with the `-settings` flag.
|
||||||
@@ -96,6 +102,7 @@ Snapshots:
|
|||||||
- `settings.hourly_snapshot_max_age_days`: retention for hourly tables
|
- `settings.hourly_snapshot_max_age_days`: retention for hourly tables
|
||||||
- `settings.daily_snapshot_max_age_months`: retention for daily tables
|
- `settings.daily_snapshot_max_age_months`: retention for daily tables
|
||||||
- `settings.snapshot_cleanup_cron`: cron expression for cleanup job
|
- `settings.snapshot_cleanup_cron`: cron expression for cleanup job
|
||||||
|
- `settings.reports_dir`: directory to store generated XLSX reports (default: `/var/lib/vctp/reports`)
|
||||||
|
|
||||||
Filters/chargeback:
|
Filters/chargeback:
|
||||||
- `settings.tenants_to_filter`: list of tenant name patterns to exclude
|
- `settings.tenants_to_filter`: list of tenant name patterns to exclude
|
||||||
|
|||||||
229
db/helpers.go
229
db/helpers.go
@@ -386,20 +386,31 @@ func BuildDailySummaryInsert(tableName string, unionQuery string) (string, error
|
|||||||
insert := fmt.Sprintf(`
|
insert := fmt.Sprintf(`
|
||||||
WITH snapshots AS (
|
WITH snapshots AS (
|
||||||
%s
|
%s
|
||||||
), ordered AS (
|
), totals AS (
|
||||||
|
SELECT COUNT(DISTINCT "SnapshotTime") AS total_samples FROM snapshots
|
||||||
|
), agg AS (
|
||||||
SELECT
|
SELECT
|
||||||
s.*,
|
"InventoryId", "Name", "Vcenter", "VmId", "EventKey", "CloudId",
|
||||||
LEAD("SnapshotTime") OVER (PARTITION BY "VmId", "Vcenter" ORDER BY "SnapshotTime") AS next_snapshot,
|
MIN(NULLIF("CreationTime", 0)) AS any_creation,
|
||||||
LEAD("SnapshotTime") OVER (PARTITION BY "VmId", "Vcenter" ORDER BY "SnapshotTime") - "SnapshotTime" AS interval_seconds
|
MAX(NULLIF("DeletionTime", 0)) AS any_deletion,
|
||||||
FROM snapshots s
|
MIN(CASE WHEN "IsPresent" = 'TRUE' THEN "SnapshotTime" END) AS first_present,
|
||||||
), weighted AS (
|
MAX(CASE WHEN "IsPresent" = 'TRUE' THEN "SnapshotTime" END) AS last_present,
|
||||||
SELECT
|
MAX(CASE WHEN "IsPresent" = 'FALSE' THEN "SnapshotTime" END) AS last_absent,
|
||||||
o.*,
|
"Datacenter", "Cluster", "Folder", "ProvisionedDisk", "VcpuCount",
|
||||||
CASE
|
"RamGB", "IsTemplate", "PoweredOn", "SrmPlaceholder", "VmUuid",
|
||||||
WHEN o.interval_seconds IS NULL OR o.interval_seconds <= 0 THEN 3600
|
SUM(CASE WHEN "IsPresent" = 'TRUE' THEN 1 ELSE 0 END) AS samples_present,
|
||||||
ELSE o.interval_seconds
|
SUM(CASE WHEN "IsPresent" = 'TRUE' AND "VcpuCount" IS NOT NULL THEN "VcpuCount" ELSE 0 END) AS sum_vcpu,
|
||||||
END AS weight_seconds
|
SUM(CASE WHEN "IsPresent" = 'TRUE' AND "RamGB" IS NOT NULL THEN "RamGB" ELSE 0 END) AS sum_ram,
|
||||||
FROM ordered o
|
SUM(CASE WHEN "IsPresent" = 'TRUE' AND "ProvisionedDisk" IS NOT NULL THEN "ProvisionedDisk" ELSE 0 END) AS sum_disk,
|
||||||
|
SUM(CASE WHEN "IsPresent" = 'TRUE' AND LOWER("ResourcePool") = 'tin' THEN 1 ELSE 0 END) AS tin_hits,
|
||||||
|
SUM(CASE WHEN "IsPresent" = 'TRUE' AND LOWER("ResourcePool") = 'bronze' THEN 1 ELSE 0 END) AS bronze_hits,
|
||||||
|
SUM(CASE WHEN "IsPresent" = 'TRUE' AND LOWER("ResourcePool") = 'silver' THEN 1 ELSE 0 END) AS silver_hits,
|
||||||
|
SUM(CASE WHEN "IsPresent" = 'TRUE' AND LOWER("ResourcePool") = 'gold' THEN 1 ELSE 0 END) AS gold_hits
|
||||||
|
FROM snapshots
|
||||||
|
GROUP BY
|
||||||
|
"InventoryId", "Name", "Vcenter", "VmId", "EventKey", "CloudId",
|
||||||
|
"Datacenter", "Cluster", "Folder", "ProvisionedDisk", "VcpuCount",
|
||||||
|
"RamGB", "IsTemplate", "PoweredOn", "SrmPlaceholder", "VmUuid"
|
||||||
)
|
)
|
||||||
INSERT INTO %s (
|
INSERT INTO %s (
|
||||||
"InventoryId", "Name", "Vcenter", "VmId", "EventKey", "CloudId", "CreationTime", "DeletionTime",
|
"InventoryId", "Name", "Vcenter", "VmId", "EventKey", "CloudId", "CreationTime", "DeletionTime",
|
||||||
@@ -410,73 +421,69 @@ INSERT INTO %s (
|
|||||||
"Tin", "Bronze", "Silver", "Gold"
|
"Tin", "Bronze", "Silver", "Gold"
|
||||||
)
|
)
|
||||||
SELECT
|
SELECT
|
||||||
"InventoryId", "Name", "Vcenter", "VmId", "EventKey", "CloudId",
|
agg."InventoryId", agg."Name", agg."Vcenter", agg."VmId", agg."EventKey", agg."CloudId",
|
||||||
COALESCE(NULLIF("CreationTime", 0), MIN(CASE WHEN "IsPresent" = 'TRUE' THEN "SnapshotTime" END), 0) AS "CreationTime",
|
COALESCE(agg.any_creation, agg.first_present, 0) AS "CreationTime",
|
||||||
COALESCE(NULLIF("DeletionTime", 0), MAX(CASE WHEN "IsPresent" = 'TRUE' THEN "SnapshotTime" END), 0) AS "DeletionTime",
|
CASE
|
||||||
|
WHEN agg.last_present IS NULL THEN NULLIF(agg.any_deletion, 0)
|
||||||
|
WHEN agg.last_absent IS NOT NULL AND agg.last_absent > agg.last_present THEN agg.last_absent
|
||||||
|
ELSE NULLIF(agg.any_deletion, 0)
|
||||||
|
END AS "DeletionTime",
|
||||||
(
|
(
|
||||||
SELECT s2."ResourcePool"
|
SELECT s2."ResourcePool"
|
||||||
FROM weighted s2
|
FROM snapshots s2
|
||||||
WHERE s2."VmId" = weighted."VmId"
|
WHERE s2."VmId" = agg."VmId"
|
||||||
AND s2."Vcenter" = weighted."Vcenter"
|
AND s2."Vcenter" = agg."Vcenter"
|
||||||
AND s2."IsPresent" = 'TRUE'
|
AND s2."IsPresent" = 'TRUE'
|
||||||
ORDER BY s2."SnapshotTime" DESC
|
ORDER BY s2."SnapshotTime" DESC
|
||||||
LIMIT 1
|
LIMIT 1
|
||||||
) AS "ResourcePool",
|
) AS "ResourcePool",
|
||||||
"Datacenter", "Cluster", "Folder", "ProvisionedDisk", "VcpuCount",
|
agg."Datacenter", agg."Cluster", agg."Folder", agg."ProvisionedDisk", agg."VcpuCount",
|
||||||
"RamGB", "IsTemplate", "PoweredOn", "SrmPlaceholder", "VmUuid",
|
agg."RamGB", agg."IsTemplate", agg."PoweredOn", agg."SrmPlaceholder", agg."VmUuid",
|
||||||
SUM(CASE WHEN "IsPresent" = 'TRUE' THEN 1 ELSE 0 END) AS "SamplesPresent",
|
agg.samples_present AS "SamplesPresent",
|
||||||
CASE WHEN SUM(CASE WHEN "IsPresent" = 'TRUE' THEN weight_seconds ELSE 0 END) > 0
|
CASE WHEN totals.total_samples > 0
|
||||||
THEN SUM(CASE WHEN "IsPresent" = 'TRUE' AND "VcpuCount" IS NOT NULL THEN "VcpuCount" * weight_seconds ELSE 0 END)
|
THEN 1.0 * agg.sum_vcpu / totals.total_samples
|
||||||
/ SUM(CASE WHEN "IsPresent" = 'TRUE' THEN weight_seconds ELSE 0 END)
|
|
||||||
ELSE NULL END AS "AvgVcpuCount",
|
ELSE NULL END AS "AvgVcpuCount",
|
||||||
CASE WHEN SUM(CASE WHEN "IsPresent" = 'TRUE' THEN weight_seconds ELSE 0 END) > 0
|
CASE WHEN totals.total_samples > 0
|
||||||
THEN SUM(CASE WHEN "IsPresent" = 'TRUE' AND "RamGB" IS NOT NULL THEN "RamGB" * weight_seconds ELSE 0 END)
|
THEN 1.0 * agg.sum_ram / totals.total_samples
|
||||||
/ SUM(CASE WHEN "IsPresent" = 'TRUE' THEN weight_seconds ELSE 0 END)
|
|
||||||
ELSE NULL END AS "AvgRamGB",
|
ELSE NULL END AS "AvgRamGB",
|
||||||
CASE WHEN SUM(CASE WHEN "IsPresent" = 'TRUE' THEN weight_seconds ELSE 0 END) > 0
|
CASE WHEN totals.total_samples > 0
|
||||||
THEN SUM(CASE WHEN "IsPresent" = 'TRUE' AND "ProvisionedDisk" IS NOT NULL THEN "ProvisionedDisk" * weight_seconds ELSE 0 END)
|
THEN 1.0 * agg.sum_disk / totals.total_samples
|
||||||
/ SUM(CASE WHEN "IsPresent" = 'TRUE' THEN weight_seconds ELSE 0 END)
|
|
||||||
ELSE NULL END AS "AvgProvisionedDisk",
|
ELSE NULL END AS "AvgProvisionedDisk",
|
||||||
CASE WHEN SUM(weight_seconds) > 0
|
CASE WHEN totals.total_samples > 0
|
||||||
THEN SUM(CASE WHEN "IsPresent" = 'TRUE' THEN weight_seconds ELSE 0 END) / SUM(weight_seconds)
|
THEN 1.0 * agg.samples_present / totals.total_samples
|
||||||
ELSE NULL END AS "AvgIsPresent",
|
ELSE NULL END AS "AvgIsPresent",
|
||||||
CASE WHEN SUM(CASE WHEN "IsPresent" = 'TRUE' THEN weight_seconds ELSE 0 END) > 0
|
CASE WHEN agg.samples_present > 0
|
||||||
THEN 100.0 * SUM(CASE WHEN "IsPresent" = 'TRUE' AND LOWER("ResourcePool") = 'tin' THEN weight_seconds ELSE 0 END)
|
THEN 100.0 * agg.tin_hits / agg.samples_present
|
||||||
/ SUM(CASE WHEN "IsPresent" = 'TRUE' THEN weight_seconds ELSE 0 END)
|
|
||||||
ELSE NULL END AS "PoolTinPct",
|
ELSE NULL END AS "PoolTinPct",
|
||||||
CASE WHEN SUM(CASE WHEN "IsPresent" = 'TRUE' THEN weight_seconds ELSE 0 END) > 0
|
CASE WHEN agg.samples_present > 0
|
||||||
THEN 100.0 * SUM(CASE WHEN "IsPresent" = 'TRUE' AND LOWER("ResourcePool") = 'bronze' THEN weight_seconds ELSE 0 END)
|
THEN 100.0 * agg.bronze_hits / agg.samples_present
|
||||||
/ SUM(CASE WHEN "IsPresent" = 'TRUE' THEN weight_seconds ELSE 0 END)
|
|
||||||
ELSE NULL END AS "PoolBronzePct",
|
ELSE NULL END AS "PoolBronzePct",
|
||||||
CASE WHEN SUM(CASE WHEN "IsPresent" = 'TRUE' THEN weight_seconds ELSE 0 END) > 0
|
CASE WHEN agg.samples_present > 0
|
||||||
THEN 100.0 * SUM(CASE WHEN "IsPresent" = 'TRUE' AND LOWER("ResourcePool") = 'silver' THEN weight_seconds ELSE 0 END)
|
THEN 100.0 * agg.silver_hits / agg.samples_present
|
||||||
/ SUM(CASE WHEN "IsPresent" = 'TRUE' THEN weight_seconds ELSE 0 END)
|
|
||||||
ELSE NULL END AS "PoolSilverPct",
|
ELSE NULL END AS "PoolSilverPct",
|
||||||
CASE WHEN SUM(CASE WHEN "IsPresent" = 'TRUE' THEN weight_seconds ELSE 0 END) > 0
|
CASE WHEN agg.samples_present > 0
|
||||||
THEN 100.0 * SUM(CASE WHEN "IsPresent" = 'TRUE' AND LOWER("ResourcePool") = 'gold' THEN weight_seconds ELSE 0 END)
|
THEN 100.0 * agg.gold_hits / agg.samples_present
|
||||||
/ SUM(CASE WHEN "IsPresent" = 'TRUE' THEN weight_seconds ELSE 0 END)
|
|
||||||
ELSE NULL END AS "PoolGoldPct",
|
ELSE NULL END AS "PoolGoldPct",
|
||||||
CASE WHEN SUM(CASE WHEN "IsPresent" = 'TRUE' THEN weight_seconds ELSE 0 END) > 0
|
CASE WHEN agg.samples_present > 0
|
||||||
THEN 100.0 * SUM(CASE WHEN "IsPresent" = 'TRUE' AND LOWER("ResourcePool") = 'tin' THEN weight_seconds ELSE 0 END)
|
THEN 100.0 * agg.tin_hits / agg.samples_present
|
||||||
/ SUM(CASE WHEN "IsPresent" = 'TRUE' THEN weight_seconds ELSE 0 END)
|
|
||||||
ELSE NULL END AS "Tin",
|
ELSE NULL END AS "Tin",
|
||||||
CASE WHEN SUM(CASE WHEN "IsPresent" = 'TRUE' THEN weight_seconds ELSE 0 END) > 0
|
CASE WHEN agg.samples_present > 0
|
||||||
THEN 100.0 * SUM(CASE WHEN "IsPresent" = 'TRUE' AND LOWER("ResourcePool") = 'bronze' THEN weight_seconds ELSE 0 END)
|
THEN 100.0 * agg.bronze_hits / agg.samples_present
|
||||||
/ SUM(CASE WHEN "IsPresent" = 'TRUE' THEN weight_seconds ELSE 0 END)
|
|
||||||
ELSE NULL END AS "Bronze",
|
ELSE NULL END AS "Bronze",
|
||||||
CASE WHEN SUM(CASE WHEN "IsPresent" = 'TRUE' THEN weight_seconds ELSE 0 END) > 0
|
CASE WHEN agg.samples_present > 0
|
||||||
THEN 100.0 * SUM(CASE WHEN "IsPresent" = 'TRUE' AND LOWER("ResourcePool") = 'silver' THEN weight_seconds ELSE 0 END)
|
THEN 100.0 * agg.silver_hits / agg.samples_present
|
||||||
/ SUM(CASE WHEN "IsPresent" = 'TRUE' THEN weight_seconds ELSE 0 END)
|
|
||||||
ELSE NULL END AS "Silver",
|
ELSE NULL END AS "Silver",
|
||||||
CASE WHEN SUM(CASE WHEN "IsPresent" = 'TRUE' THEN weight_seconds ELSE 0 END) > 0
|
CASE WHEN agg.samples_present > 0
|
||||||
THEN 100.0 * SUM(CASE WHEN "IsPresent" = 'TRUE' AND LOWER("ResourcePool") = 'gold' THEN weight_seconds ELSE 0 END)
|
THEN 100.0 * agg.gold_hits / agg.samples_present
|
||||||
/ SUM(CASE WHEN "IsPresent" = 'TRUE' THEN weight_seconds ELSE 0 END)
|
|
||||||
ELSE NULL END AS "Gold"
|
ELSE NULL END AS "Gold"
|
||||||
FROM weighted
|
FROM agg
|
||||||
|
CROSS JOIN totals
|
||||||
GROUP BY
|
GROUP BY
|
||||||
"InventoryId", "Name", "Vcenter", "VmId", "EventKey", "CloudId",
|
agg."InventoryId", agg."Name", agg."Vcenter", agg."VmId", agg."EventKey", agg."CloudId",
|
||||||
"Datacenter", "Cluster", "Folder", "ProvisionedDisk", "VcpuCount",
|
agg."Datacenter", agg."Cluster", agg."Folder", agg."ProvisionedDisk", agg."VcpuCount",
|
||||||
"RamGB", "IsTemplate", "PoweredOn", "SrmPlaceholder", "VmUuid";
|
agg."RamGB", agg."IsTemplate", agg."PoweredOn", agg."SrmPlaceholder", agg."VmUuid",
|
||||||
|
agg.any_creation, agg.any_deletion, agg.first_present, agg.last_present, agg.last_absent,
|
||||||
|
totals.total_samples;
|
||||||
`, unionQuery, tableName)
|
`, unionQuery, tableName)
|
||||||
return insert, nil
|
return insert, nil
|
||||||
}
|
}
|
||||||
@@ -487,22 +494,18 @@ func BuildMonthlySummaryInsert(tableName string, unionQuery string) (string, err
|
|||||||
return "", err
|
return "", err
|
||||||
}
|
}
|
||||||
insert := fmt.Sprintf(`
|
insert := fmt.Sprintf(`
|
||||||
WITH snapshots AS (
|
WITH daily AS (
|
||||||
%s
|
%s
|
||||||
), ordered AS (
|
), enriched AS (
|
||||||
SELECT
|
SELECT
|
||||||
s.*,
|
d.*,
|
||||||
LEAD("SnapshotTime") OVER (PARTITION BY "VmId", "Vcenter" ORDER BY "SnapshotTime") AS next_snapshot,
|
|
||||||
LEAD("SnapshotTime") OVER (PARTITION BY "VmId", "Vcenter" ORDER BY "SnapshotTime") - "SnapshotTime" AS interval_seconds
|
|
||||||
FROM snapshots s
|
|
||||||
), weighted AS (
|
|
||||||
SELECT
|
|
||||||
o.*,
|
|
||||||
CASE
|
CASE
|
||||||
WHEN o.interval_seconds IS NULL OR o.interval_seconds <= 0 THEN 3600
|
WHEN d."AvgIsPresent" IS NOT NULL AND d."AvgIsPresent" > 0 THEN d."SamplesPresent" / d."AvgIsPresent"
|
||||||
ELSE o.interval_seconds
|
ELSE CAST(d."SamplesPresent" AS REAL)
|
||||||
END AS weight_seconds
|
END AS total_samples_day
|
||||||
FROM ordered o
|
FROM daily d
|
||||||
|
), totals AS (
|
||||||
|
SELECT COALESCE(SUM(total_samples_day), 0) AS total_samples FROM enriched
|
||||||
)
|
)
|
||||||
INSERT INTO %s (
|
INSERT INTO %s (
|
||||||
"InventoryId", "Name", "Vcenter", "VmId", "EventKey", "CloudId", "CreationTime", "DeletionTime",
|
"InventoryId", "Name", "Vcenter", "VmId", "EventKey", "CloudId", "CreationTime", "DeletionTime",
|
||||||
@@ -514,68 +517,50 @@ INSERT INTO %s (
|
|||||||
)
|
)
|
||||||
SELECT
|
SELECT
|
||||||
"InventoryId", "Name", "Vcenter", "VmId", "EventKey", "CloudId",
|
"InventoryId", "Name", "Vcenter", "VmId", "EventKey", "CloudId",
|
||||||
COALESCE(NULLIF("CreationTime", 0), MIN(CASE WHEN "IsPresent" = 'TRUE' THEN "SnapshotTime" END), 0) AS "CreationTime",
|
COALESCE(NULLIF("CreationTime", 0), MIN(NULLIF("CreationTime", 0)), 0) AS "CreationTime",
|
||||||
COALESCE(NULLIF("DeletionTime", 0), MAX(CASE WHEN "IsPresent" = 'TRUE' THEN "SnapshotTime" END), 0) AS "DeletionTime",
|
NULLIF(MAX(NULLIF("DeletionTime", 0)), 0) AS "DeletionTime",
|
||||||
(
|
MAX("ResourcePool") AS "ResourcePool",
|
||||||
SELECT s2."ResourcePool"
|
|
||||||
FROM weighted s2
|
|
||||||
WHERE s2."VmId" = weighted."VmId"
|
|
||||||
AND s2."Vcenter" = weighted."Vcenter"
|
|
||||||
AND s2."IsPresent" = 'TRUE'
|
|
||||||
ORDER BY s2."SnapshotTime" DESC
|
|
||||||
LIMIT 1
|
|
||||||
) AS "ResourcePool",
|
|
||||||
"Datacenter", "Cluster", "Folder", "ProvisionedDisk", "VcpuCount",
|
"Datacenter", "Cluster", "Folder", "ProvisionedDisk", "VcpuCount",
|
||||||
"RamGB", "IsTemplate", "PoweredOn", "SrmPlaceholder", "VmUuid",
|
"RamGB", "IsTemplate", "PoweredOn", "SrmPlaceholder", "VmUuid",
|
||||||
SUM(CASE WHEN "IsPresent" = 'TRUE' THEN 1 ELSE 0 END) AS "SamplesPresent",
|
SUM("SamplesPresent") AS "SamplesPresent",
|
||||||
CASE WHEN SUM(CASE WHEN "IsPresent" = 'TRUE' THEN weight_seconds ELSE 0 END) > 0
|
CASE WHEN totals.total_samples > 0
|
||||||
THEN SUM(CASE WHEN "IsPresent" = 'TRUE' AND "VcpuCount" IS NOT NULL THEN "VcpuCount" * weight_seconds ELSE 0 END)
|
THEN SUM(CASE WHEN "AvgVcpuCount" IS NOT NULL THEN "AvgVcpuCount" * total_samples_day ELSE 0 END) / totals.total_samples
|
||||||
/ SUM(CASE WHEN "IsPresent" = 'TRUE' THEN weight_seconds ELSE 0 END)
|
|
||||||
ELSE NULL END AS "AvgVcpuCount",
|
ELSE NULL END AS "AvgVcpuCount",
|
||||||
CASE WHEN SUM(CASE WHEN "IsPresent" = 'TRUE' THEN weight_seconds ELSE 0 END) > 0
|
CASE WHEN totals.total_samples > 0
|
||||||
THEN SUM(CASE WHEN "IsPresent" = 'TRUE' AND "RamGB" IS NOT NULL THEN "RamGB" * weight_seconds ELSE 0 END)
|
THEN SUM(CASE WHEN "AvgRamGB" IS NOT NULL THEN "AvgRamGB" * total_samples_day ELSE 0 END) / totals.total_samples
|
||||||
/ SUM(CASE WHEN "IsPresent" = 'TRUE' THEN weight_seconds ELSE 0 END)
|
|
||||||
ELSE NULL END AS "AvgRamGB",
|
ELSE NULL END AS "AvgRamGB",
|
||||||
CASE WHEN SUM(CASE WHEN "IsPresent" = 'TRUE' THEN weight_seconds ELSE 0 END) > 0
|
CASE WHEN totals.total_samples > 0
|
||||||
THEN SUM(CASE WHEN "IsPresent" = 'TRUE' AND "ProvisionedDisk" IS NOT NULL THEN "ProvisionedDisk" * weight_seconds ELSE 0 END)
|
THEN SUM(CASE WHEN "AvgProvisionedDisk" IS NOT NULL THEN "AvgProvisionedDisk" * total_samples_day ELSE 0 END) / totals.total_samples
|
||||||
/ SUM(CASE WHEN "IsPresent" = 'TRUE' THEN weight_seconds ELSE 0 END)
|
|
||||||
ELSE NULL END AS "AvgProvisionedDisk",
|
ELSE NULL END AS "AvgProvisionedDisk",
|
||||||
CASE WHEN SUM(weight_seconds) > 0
|
CASE WHEN totals.total_samples > 0
|
||||||
THEN SUM(CASE WHEN "IsPresent" = 'TRUE' THEN weight_seconds ELSE 0 END) / SUM(weight_seconds)
|
THEN SUM("SamplesPresent") * 1.0 / totals.total_samples
|
||||||
ELSE NULL END AS "AvgIsPresent",
|
ELSE NULL END AS "AvgIsPresent",
|
||||||
CASE WHEN SUM(CASE WHEN "IsPresent" = 'TRUE' THEN weight_seconds ELSE 0 END) > 0
|
CASE WHEN totals.total_samples > 0
|
||||||
THEN 100.0 * SUM(CASE WHEN "IsPresent" = 'TRUE' AND LOWER("ResourcePool") = 'tin' THEN weight_seconds ELSE 0 END)
|
THEN 100.0 * SUM(CASE WHEN "PoolTinPct" IS NOT NULL THEN ("PoolTinPct" / 100.0) * total_samples_day ELSE 0 END) / totals.total_samples
|
||||||
/ SUM(CASE WHEN "IsPresent" = 'TRUE' THEN weight_seconds ELSE 0 END)
|
|
||||||
ELSE NULL END AS "PoolTinPct",
|
ELSE NULL END AS "PoolTinPct",
|
||||||
CASE WHEN SUM(CASE WHEN "IsPresent" = 'TRUE' THEN weight_seconds ELSE 0 END) > 0
|
CASE WHEN totals.total_samples > 0
|
||||||
THEN 100.0 * SUM(CASE WHEN "IsPresent" = 'TRUE' AND LOWER("ResourcePool") = 'bronze' THEN weight_seconds ELSE 0 END)
|
THEN 100.0 * SUM(CASE WHEN "PoolBronzePct" IS NOT NULL THEN ("PoolBronzePct" / 100.0) * total_samples_day ELSE 0 END) / totals.total_samples
|
||||||
/ SUM(CASE WHEN "IsPresent" = 'TRUE' THEN weight_seconds ELSE 0 END)
|
|
||||||
ELSE NULL END AS "PoolBronzePct",
|
ELSE NULL END AS "PoolBronzePct",
|
||||||
CASE WHEN SUM(CASE WHEN "IsPresent" = 'TRUE' THEN weight_seconds ELSE 0 END) > 0
|
CASE WHEN totals.total_samples > 0
|
||||||
THEN 100.0 * SUM(CASE WHEN "IsPresent" = 'TRUE' AND LOWER("ResourcePool") = 'silver' THEN weight_seconds ELSE 0 END)
|
THEN 100.0 * SUM(CASE WHEN "PoolSilverPct" IS NOT NULL THEN ("PoolSilverPct" / 100.0) * total_samples_day ELSE 0 END) / totals.total_samples
|
||||||
/ SUM(CASE WHEN "IsPresent" = 'TRUE' THEN weight_seconds ELSE 0 END)
|
|
||||||
ELSE NULL END AS "PoolSilverPct",
|
ELSE NULL END AS "PoolSilverPct",
|
||||||
CASE WHEN SUM(CASE WHEN "IsPresent" = 'TRUE' THEN weight_seconds ELSE 0 END) > 0
|
CASE WHEN totals.total_samples > 0
|
||||||
THEN 100.0 * SUM(CASE WHEN "IsPresent" = 'TRUE' AND LOWER("ResourcePool") = 'gold' THEN weight_seconds ELSE 0 END)
|
THEN 100.0 * SUM(CASE WHEN "PoolGoldPct" IS NOT NULL THEN ("PoolGoldPct" / 100.0) * total_samples_day ELSE 0 END) / totals.total_samples
|
||||||
/ SUM(CASE WHEN "IsPresent" = 'TRUE' THEN weight_seconds ELSE 0 END)
|
|
||||||
ELSE NULL END AS "PoolGoldPct",
|
ELSE NULL END AS "PoolGoldPct",
|
||||||
CASE WHEN SUM(CASE WHEN "IsPresent" = 'TRUE' THEN weight_seconds ELSE 0 END) > 0
|
CASE WHEN totals.total_samples > 0
|
||||||
THEN 100.0 * SUM(CASE WHEN "IsPresent" = 'TRUE' AND LOWER("ResourcePool") = 'tin' THEN weight_seconds ELSE 0 END)
|
THEN 100.0 * SUM(CASE WHEN "Tin" IS NOT NULL THEN ("Tin" / 100.0) * total_samples_day ELSE 0 END) / totals.total_samples
|
||||||
/ SUM(CASE WHEN "IsPresent" = 'TRUE' THEN weight_seconds ELSE 0 END)
|
|
||||||
ELSE NULL END AS "Tin",
|
ELSE NULL END AS "Tin",
|
||||||
CASE WHEN SUM(CASE WHEN "IsPresent" = 'TRUE' THEN weight_seconds ELSE 0 END) > 0
|
CASE WHEN totals.total_samples > 0
|
||||||
THEN 100.0 * SUM(CASE WHEN "IsPresent" = 'TRUE' AND LOWER("ResourcePool") = 'bronze' THEN weight_seconds ELSE 0 END)
|
THEN 100.0 * SUM(CASE WHEN "Bronze" IS NOT NULL THEN ("Bronze" / 100.0) * total_samples_day ELSE 0 END) / totals.total_samples
|
||||||
/ SUM(CASE WHEN "IsPresent" = 'TRUE' THEN weight_seconds ELSE 0 END)
|
|
||||||
ELSE NULL END AS "Bronze",
|
ELSE NULL END AS "Bronze",
|
||||||
CASE WHEN SUM(CASE WHEN "IsPresent" = 'TRUE' THEN weight_seconds ELSE 0 END) > 0
|
CASE WHEN totals.total_samples > 0
|
||||||
THEN 100.0 * SUM(CASE WHEN "IsPresent" = 'TRUE' AND LOWER("ResourcePool") = 'silver' THEN weight_seconds ELSE 0 END)
|
THEN 100.0 * SUM(CASE WHEN "Silver" IS NOT NULL THEN ("Silver" / 100.0) * total_samples_day ELSE 0 END) / totals.total_samples
|
||||||
/ SUM(CASE WHEN "IsPresent" = 'TRUE' THEN weight_seconds ELSE 0 END)
|
|
||||||
ELSE NULL END AS "Silver",
|
ELSE NULL END AS "Silver",
|
||||||
CASE WHEN SUM(CASE WHEN "IsPresent" = 'TRUE' THEN weight_seconds ELSE 0 END) > 0
|
CASE WHEN totals.total_samples > 0
|
||||||
THEN 100.0 * SUM(CASE WHEN "IsPresent" = 'TRUE' AND LOWER("ResourcePool") = 'gold' THEN weight_seconds ELSE 0 END)
|
THEN 100.0 * SUM(CASE WHEN "Gold" IS NOT NULL THEN ("Gold" / 100.0) * total_samples_day ELSE 0 END) / totals.total_samples
|
||||||
/ SUM(CASE WHEN "IsPresent" = 'TRUE' THEN weight_seconds ELSE 0 END)
|
|
||||||
ELSE NULL END AS "Gold"
|
ELSE NULL END AS "Gold"
|
||||||
FROM weighted
|
FROM enriched
|
||||||
|
CROSS JOIN totals
|
||||||
GROUP BY
|
GROUP BY
|
||||||
"InventoryId", "Name", "Vcenter", "VmId", "EventKey", "CloudId",
|
"InventoryId", "Name", "Vcenter", "VmId", "EventKey", "CloudId",
|
||||||
"Datacenter", "Cluster", "Folder", "ProvisionedDisk", "VcpuCount",
|
"Datacenter", "Cluster", "Folder", "ProvisionedDisk", "VcpuCount",
|
||||||
|
|||||||
Reference in New Issue
Block a user