Version: 1.7.0
- Setup & Initialization
- Data Preparation
- Aggregate Functions Deep Dive
- Window Functions Deep Dive
- Statistical Analysis
- Real-World Examples
- Performance Tuning
Create a new console application:
dotnet new console -n AnalyticsDemo
cd AnalyticsDemo
dotnet add package SharpCoreDB --version 1.7.0
dotnet add package SharpCoreDB.Analytics --version 1.7.0using Microsoft.Extensions.DependencyInjection;
using SharpCoreDB;
using SharpCoreDB.Analytics;
var services = new ServiceCollection();
// Register SharpCoreDB
services.AddSharpCoreDB();
// Add analytics services
services.AddAnalyticsEngine();
var provider = services.BuildServiceProvider();
var database = provider.GetRequiredService<IDatabase>();
// Initialize database with sample data
await InitializeSampleDataAsync(database);private static async Task InitializeSampleDataAsync(IDatabase database)
{
// Create employees table
await database.ExecuteAsync(@"
CREATE TABLE IF NOT EXISTS employees (
id INT PRIMARY KEY,
name TEXT NOT NULL,
department TEXT NOT NULL,
hire_date TEXT NOT NULL,
salary DECIMAL NOT NULL,
manager_id INT,
performance_score FLOAT
)
");
// Create sales table
await database.ExecuteAsync(@"
CREATE TABLE IF NOT EXISTS sales (
id INT PRIMARY KEY,
employee_id INT NOT NULL,
sale_date TEXT NOT NULL,
amount DECIMAL NOT NULL,
region TEXT NOT NULL
)
");
// Insert sample data
var employees = new[]
{
"INSERT INTO employees VALUES (1, 'Alice Johnson', 'Engineering', '2020-03-15', 95000, NULL, 4.8)",
"INSERT INTO employees VALUES (2, 'Bob Smith', 'Engineering', '2021-06-20', 85000, 1, 4.5)",
"INSERT INTO employees VALUES (3, 'Carol Davis', 'Sales', '2019-01-10', 75000, NULL, 4.3)",
"INSERT INTO employees VALUES (4, 'David Wilson', 'Sales', '2022-04-05', 65000, 3, 4.0)",
"INSERT INTO employees VALUES (5, 'Emma Brown', 'Marketing', '2023-08-15', 70000, NULL, 4.2)",
"INSERT INTO employees VALUES (6, 'Frank Miller', 'Engineering', '2023-02-28', 80000, 1, 3.9)",
};
foreach (var stmt in employees)
{
await database.ExecuteAsync(stmt);
}
// Insert sales data
var sales = new[]
{
"INSERT INTO sales VALUES (1, 1, '2026-01-01', 50000, 'North')",
"INSERT INTO sales VALUES (2, 1, '2026-01-02', 45000, 'North')",
"INSERT INTO sales VALUES (3, 2, '2026-01-01', 30000, 'North')",
"INSERT INTO sales VALUES (4, 3, '2026-01-01', 60000, 'South')",
"INSERT INTO sales VALUES (5, 3, '2026-01-02', 55000, 'South')",
"INSERT INTO sales VALUES (6, 4, '2026-01-01', 25000, 'South')",
};
foreach (var stmt in sales)
{
await database.ExecuteAsync(stmt);
}
await database.FlushAsync();
}COUNT aggregates can work in different ways:
// Example 1: Count all rows
var totalEmps = await database.QuerySingleAsync(
"SELECT COUNT(*) as total FROM employees"
);
Console.WriteLine($"Total employees: {totalEmps["total"]}"); // 6
// Example 2: Count non-NULL values
var managed = await database.QuerySingleAsync(
"SELECT COUNT(manager_id) as managed_count FROM employees"
);
Console.WriteLine($"Employees with managers: {managed["managed_count"]}"); // 2
// Example 3: Count distinct departments
var depts = await database.QuerySingleAsync(
"SELECT COUNT(DISTINCT department) as dept_count FROM employees"
);
Console.WriteLine($"Departments: {depts["dept_count"]}"); // 3// Total and average salary
var salaryStats = await database.QuerySingleAsync(@"
SELECT
SUM(salary) as total_payroll,
AVG(salary) as avg_salary,
COUNT(*) as employee_count
FROM employees
");
var totalPayroll = (decimal)salaryStats["total_payroll"];
var avgSalary = (decimal)salaryStats["avg_salary"];
Console.WriteLine($"Payroll: ${totalPayroll:N2}");
Console.WriteLine($"Average: ${avgSalary:N2}");
// By department
var byDept = await database.QueryAsync(@"
SELECT
department,
COUNT(*) as count,
SUM(salary) as total,
AVG(salary) as average,
MIN(salary) as minimum,
MAX(salary) as maximum
FROM employees
GROUP BY department
ORDER BY total DESC
");
foreach (var row in byDept)
{
Console.WriteLine($"\n{row["department"]}:");
Console.WriteLine($" Employees: {row["count"]}");
Console.WriteLine($" Total: ${row["total"]}");
Console.WriteLine($" Avg: ${row["average"]}");
Console.WriteLine($" Range: ${row["minimum"]} - ${row["maximum"]}");
}// Analyze salary distribution
var distribution = await database.QuerySingleAsync(@"
SELECT
COUNT(*) as total,
AVG(salary) as mean,
MIN(salary) as min_val,
MAX(salary) as max_val,
STDDEV(salary) as std_dev,
VARIANCE(salary) as variance,
PERCENTILE(salary, 0.25) as q1,
PERCENTILE(salary, 0.50) as median,
PERCENTILE(salary, 0.75) as q3
FROM employees
");
var mean = (decimal)distribution["mean"];
var stdDev = (decimal)distribution["std_dev"];
var q1 = (decimal)distribution["q1"];
var median = (decimal)distribution["median"];
var q3 = (decimal)distribution["q3"];
Console.WriteLine("Salary Distribution:");
Console.WriteLine($" Mean: ${mean:N2}");
Console.WriteLine($" Std Dev: ${stdDev:N2}");
Console.WriteLine($" Q1 (25%): ${q1:N2}");
Console.WriteLine($" Median (50%): ${median:N2}");
Console.WriteLine($" Q3 (75%): ${q3:N2}");
Console.WriteLine($" IQR: ${q3 - q1:N2}");// Rank employees by salary within each department
var ranked = await database.QueryAsync(@"
SELECT
name,
department,
salary,
ROW_NUMBER() OVER (PARTITION BY department ORDER BY salary DESC) as rank_in_dept,
ROW_NUMBER() OVER (ORDER BY salary DESC) as overall_rank
FROM employees
ORDER BY department, overall_rank
");
Console.WriteLine("Department Rankings:");
foreach (var emp in ranked)
{
Console.WriteLine(
$"{emp["name"],-20} | {emp["department"],-12} | " +
$"${emp["salary"],-8} | Dept Rank: {emp["rank_in_dept"]} | Overall: {emp["overall_rank"]}"
);
}// Show difference between RANK and DENSE_RANK
var rankings = await database.QueryAsync(@"
SELECT
name,
performance_score,
RANK() OVER (ORDER BY performance_score DESC) as rank_with_gaps,
DENSE_RANK() OVER (ORDER BY performance_score DESC) as dense_rank
FROM employees
ORDER BY performance_score DESC
");
Console.WriteLine("Performance Rankings:");
Console.WriteLine("Name | Score | RANK | DENSE_RANK");
Console.WriteLine(new string('-', 55));
foreach (var row in rankings)
{
Console.WriteLine(
$"{(string)row["name"],-20} | {(float)row["performance_score"],5:F1} | " +
$"{(int)row["rank_with_gaps"],4} | {(int)row["dense_rank"],10}"
);
}// Running total of sales by date and region
var running = await database.QueryAsync(@"
SELECT
sale_date,
region,
amount,
SUM(amount) OVER (
PARTITION BY region
ORDER BY sale_date
ROWS BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW
) as running_total
FROM sales
ORDER BY region, sale_date
");
Console.WriteLine("Running Totals by Region:");
foreach (var sale in running)
{
Console.WriteLine(
$"{sale["sale_date"]} | {sale["region"],-8} | " +
$"${sale["amount"]:N0} | Running: ${sale["running_total"]:N0}"
);
}// Find employees earning more than 2 standard deviations from mean
var outliers = await database.QueryAsync(@"
SELECT
name,
salary,
(SELECT AVG(salary) FROM employees) as company_avg,
(SELECT STDDEV(salary) FROM employees) as std_dev,
salary - (SELECT AVG(salary) FROM employees) as diff_from_avg,
ROUND(
(salary - (SELECT AVG(salary) FROM employees)) /
(SELECT STDDEV(salary) FROM employees),
2
) as z_score,
CASE
WHEN ABS(salary - (SELECT AVG(salary) FROM employees)) >
2 * (SELECT STDDEV(salary) FROM employees)
THEN 'OUTLIER'
ELSE 'Normal'
END as classification
FROM employees
");
Console.WriteLine("Outlier Analysis:");
foreach (var emp in outliers)
{
Console.WriteLine(
$"{(string)emp["name"],-20} | Salary: ${(decimal)emp["salary"],8:N0} | " +
$"Z-Score: {(decimal)emp["z_score"],6:F2} | {(string)emp["classification"]}"
);
}// Analyze correlation between performance and salary
var correlation = await database.QuerySingleAsync(@"
SELECT CORRELATION(salary, performance_score) as corr_salary_perf
FROM employees
");
var corr = (double)correlation["corr_salary_perf"];
Console.WriteLine($"Correlation (Salary vs Performance): {corr:F3}");
Console.WriteLine($"Interpretation: ", corr switch
{
> 0.7 => "Strong positive correlation",
> 0.3 => "Moderate positive correlation",
> 0 => "Weak positive correlation",
0 => "No correlation",
> -0.3 => "Weak negative correlation",
> -0.7 => "Moderate negative correlation",
_ => "Strong negative correlation"
});public class SalesAnalytics
{
public async Task GenerateDashboardAsync(IDatabase database)
{
var dashboard = await database.QueryAsync(@"
SELECT
e.name,
e.department,
COUNT(s.id) as transactions,
SUM(s.amount) as total_sales,
AVG(s.amount) as avg_transaction,
MAX(s.amount) as largest_sale,
MIN(s.amount) as smallest_sale,
ROW_NUMBER() OVER (ORDER BY SUM(s.amount) DESC) as sales_rank
FROM employees e
LEFT JOIN sales s ON e.id = s.employee_id
GROUP BY e.id, e.name, e.department
ORDER BY total_sales DESC
");
Console.WriteLine("Sales Performance Dashboard:");
Console.WriteLine(new string('=', 100));
foreach (var emp in dashboard)
{
Console.WriteLine(
$"#{(int)emp["sales_rank"]} | {(string)emp["name"],-20} | " +
$"Dept: {(string)emp["department"],-12} | " +
$"Transactions: {(int)emp["transactions"]} | " +
$"Total: ${(decimal)emp["total_sales"]:N0} | " +
$"Avg: ${(decimal)emp["avg_transaction"]:N0}"
);
}
}
}public class DepartmentAnalytics
{
public async Task GenerateReportAsync(IDatabase database)
{
var report = await database.QueryAsync(@"
SELECT
department,
COUNT(*) as headcount,
ROUND(AVG(salary), 2) as avg_salary,
MIN(salary) as min_salary,
MAX(salary) as max_salary,
ROUND(STDDEV(salary), 2) as salary_stddev,
ROUND(AVG(performance_score), 2) as avg_performance,
COUNT(CASE WHEN performance_score >= 4.5 THEN 1 END) as high_performers
FROM employees
GROUP BY department
HAVING COUNT(*) > 0
ORDER BY avg_salary DESC
");
Console.WriteLine("\nDepartment Performance Report:");
Console.WriteLine(new string('=', 120));
foreach (var dept in report)
{
Console.WriteLine(
$"\n{(string)dept["department"]}\n" +
$" Headcount: {(int)dept["headcount"]}\n" +
$" Avg Salary: ${(decimal)dept["avg_salary"]:N2}\n" +
$" Salary Range: ${(decimal)dept["min_salary"]:N0} - ${(decimal)dept["max_salary"]:N0}\n" +
$" Salary Std Dev: ${(decimal)dept["salary_stddev"]:N2}\n" +
$" Avg Performance: {(decimal)dept["avg_performance"]:F2}/5.0\n" +
$" High Performers (≥4.5): {(int)dept["high_performers"]}"
);
}
}
}public async Task AnalyzeCompensationEquityAsync(IDatabase database)
{
var equity = await database.QueryAsync(@"
SELECT
name,
department,
salary,
AVG(salary) OVER (PARTITION BY department) as dept_avg,
salary - AVG(salary) OVER (PARTITION BY department) as variance_from_dept_avg,
ROUND(
100.0 * (salary - AVG(salary) OVER (PARTITION BY department)) /
AVG(salary) OVER (PARTITION BY department),
2
) as pct_variance,
PERCENTILE(salary, 0.5) OVER (PARTITION BY department) as dept_median,
CASE
WHEN salary < AVG(salary) OVER (PARTITION BY department) - STDDEV(salary) OVER (PARTITION BY department)
THEN 'Significantly Below Market'
WHEN salary < AVG(salary) OVER (PARTITION BY department)
THEN 'Below Market'
WHEN salary < AVG(salary) OVER (PARTITION BY department) + STDDEV(salary) OVER (PARTITION BY department)
THEN 'Market Rate'
ELSE 'Above Market'
END as market_position
FROM employees
ORDER BY department, salary DESC
");
Console.WriteLine("\nCompensation Equity Analysis:");
foreach (var emp in equity)
{
Console.WriteLine(
$"{(string)emp["name"],-20} | Dept Avg: ${(decimal)emp["dept_avg"]:N0} | " +
$"Variance: {(decimal)emp["pct_variance"]:+0.0%;-0.0%} | " +
$"{(string)emp["market_position"]}"
);
}
}// Create indexes on columns used in aggregation/partitioning
await database.ExecuteAsync(
"CREATE INDEX idx_employees_department ON employees(department)"
);
await database.ExecuteAsync(
"CREATE INDEX idx_sales_employee_date ON sales(employee_id, sale_date)"
);
await database.ExecuteAsync(
"CREATE INDEX idx_sales_region ON sales(region)"
);// Pattern 1: Pre-filter before aggregation
var optimized = await database.QueryAsync(@"
SELECT
department,
COUNT(*) as count,
AVG(salary) as avg_salary
FROM employees
WHERE hire_date >= '2023-01-01'
GROUP BY department
");
// Pattern 2: Use partitioning instead of subqueries
var efficient = await database.QueryAsync(@"
SELECT
name,
salary,
AVG(salary) OVER (PARTITION BY department) as dept_avg,
salary - AVG(salary) OVER (PARTITION BY department) as diff
FROM employees
");
// Pattern 3: Combine aggregates in single query
var combined = await database.QueryAsync(@"
SELECT
department,
COUNT(*) as emp_count,
SUM(salary) as total_salary,
AVG(salary) as avg_salary,
STDDEV(salary) as salary_stddev
FROM employees
GROUP BY department
");The Analytics Engine in SharpCoreDB v1.3.5 provides:
✅ Basic Aggregates - COUNT, SUM, AVG, MIN, MAX ✅ Statistical Functions - STDDEV, VARIANCE, PERCENTILE, CORRELATION ✅ Window Functions - ROW_NUMBER, RANK, DENSE_RANK with PARTITION BY ✅ Performance - 150-680x faster than SQLite ✅ Production Ready - Fully tested and optimized
For more information, see:
- Analytics README - Feature overview
- Manual - Complete guide
- CHANGELOG - Version history
Last Updated: February 19, 2026 | Phase 9.2