Employee Performance Analysis

L3
ModelContextProtocolPostgresEmployees

Create performance evaluation system analyzing career progression patterns and salary equity for promotion and compensation decisions.

Created by Lingxiao Du
2025-08-14
Reporting And AnalyticsStatistical AggregationSchema Design

Model Ranking

Click on the dots to view the trajectory of each task run
Model
Run Results
Pass@4
Pass^4
Avg Time
Avg Turns
Input Tokens
Output Tokens
Total Tokens
DeepSeek
deepseek-chat
4
/4
238.1s
19.3
94,444
3,025
97,469
Grok
grok-code-fast-1
4
/4
34.0s
14.5
94,293
3,207
97,500
OpenAI
gpt-5-high
3
/4
378.7s
12.8
68,570
14,377
82,947
OpenAI
gpt-5-low
3
/4
161.1s
10.5
33,477
8,241
41,717
OpenAI
gpt-5-medium
3
/4
175.6s
12.3
57,512
7,745
65,256
OpenAI
gpt-5-mini-high
3
/4
92.6s
10.0
43,116
10,884
53,999
OpenAI
gpt-5-mini-medium
3
/4
46.5s
9.8
39,520
4,112
43,632
Qwen
qwen-3-coder-plus
3
/4
56.6s
18.8
148,552
1,882
150,435
Grok
grok-4
2
/4
132.7s
15.5
110,611
5,055
115,665
Claude
claude-sonnet-4
1
/4
166.4s
23.5
188,628
6,369
194,997
Claude
claude-sonnet-4-low
1
/4
129.8s
19.5
189,156
4,999
194,156
OpenAI
gpt-5-nano-high
1
/4
227.0s
12.5
59,370
43,369
102,739
OpenAI
gpt-5-nano-medium
1
/4
165.3s
8.0
34,232
14,817
49,049
OpenAI
gpt-oss-120b
1
/4
32.4s
6.8
33,307
1,809
35,116
MoonshotAI
kimi-k2-0905
1
/4
399.7s
26.5
253,984
4,129
258,112
OpenAI
o3
1
/4
56.7s
11.0
33,340
3,550
36,889
Claude
claude-opus-4-1
0
/1
--
658.9s
34.0
313,303
12,804
326,107
Claude
claude-sonnet-4-high
0
/4
134.7s
21.0
220,588
5,448
226,035
Gemini
gemini-2-5-flash
0
/4
59.1s
10.5
46,137
10,562
56,698
Gemini
gemini-2-5-pro
0
/4
110.8s
11.5
41,895
9,161
51,056
Z.ai
glm-4-5
0
/4
163.8s
18.8
94,325
5,081
99,405
OpenAI
gpt-4-1
0
/4
21.5s
8.8
17,544
629
18,174
OpenAI
gpt-4-1-mini
0
/4
23.3s
8.0
14,411
757
15,168
OpenAI
gpt-4-1-nano
0
/4
15.7s
7.5
12,506
496
13,002
OpenAI
gpt-5-mini-low
0
/4
39.7s
5.8
14,731
3,355
18,086
OpenAI
gpt-5-nano-low
0
/4
89.5s
7.5
16,066
16,764
32,830
MoonshotAI
kimi-k2-0711
0
/4
249.6s
24.0
147,772
3,896
151,667
OpenAI
o4-mini
0
/4
59.0s
5.8
12,192
5,032
17,224
Qwen
qwen-3-max
0
/4
45.6s
12.5
68,416
1,378
69,793

Task State

Enum "employees"."employee_gender" { "M" "F" } Table "employees"."department" { "id" bpchar(4) [pk, not null] "dept_name" varchar(40) [unique, not null] } Table "employees"."department_employee" { "employee_id" int8 [not null] "department_id" bpchar(4) [not null] "from_date" date [not null] "to_date" date [not null] Indexes { (employee_id, department_id) [type: btree, name: "idx_16982_primary"] department_id [type: btree, name: "idx_16982_dept_no"] } } Table "employees"."department_manager" { "employee_id" int8 [not null] "department_id" bpchar(4) [not null] "from_date" date [not null] "to_date" date [not null] Indexes { (employee_id, department_id) [type: btree, name: "idx_16985_primary"] department_id [type: btree, name: "idx_16985_dept_no"] } } Table "employees"."employee" { "id" int8 [pk, not null, increment] "birth_date" date [not null] "first_name" varchar(14) [not null] "last_name" varchar(16) [not null] "gender" employees.employee_gender [not null] "hire_date" date [not null] } Table "employees"."salary" { "employee_id" int8 [not null] "amount" int8 [not null] "from_date" date [not null] "to_date" date [not null] Indexes { (employee_id, from_date) [type: btree, name: "idx_16991_primary"] } } Table "employees"."title" { "employee_id" int8 [not null] "title" varchar(50) [not null] "from_date" date [not null] "to_date" date Indexes { (employee_id, title, from_date) [type: btree, name: "idx_16994_primary"] } } Ref "dept_emp_ibfk_1":"employees"."employee"."id" < "employees"."department_employee"."employee_id" [update: restrict, delete: cascade] Ref "dept_emp_ibfk_2":"employees"."department"."id" < "employees"."department_employee"."department_id" [update: restrict, delete: cascade] Ref "dept_manager_ibfk_1":"employees"."employee"."id" < "employees"."department_manager"."employee_id" [update: restrict, delete: cascade] Ref "dept_manager_ibfk_2":"employees"."department"."id" < "employees"."department_manager"."department_id" [update: restrict, delete: cascade] Ref "salaries_ibfk_1":"employees"."employee"."id" < "employees"."salary"."employee_id" [update: restrict, delete: cascade] Ref "titles_ibfk_1":"employees"."employee"."id" < "employees"."title"."employee_id" [update: restrict, delete: cascade]

Instruction

Create a comprehensive employee performance evaluation system that analyzes career progression patterns and salary equity across our organization. The executive team needs data-driven insights for upcoming promotion decisions and salary adjustment planning.

Your Tasks:

  1. Create the employee performance analysis table — build a table called employee_performance_analysis in the employees schema with these exact columns:

    • employee_id (bigint) — the employee's ID
    • performance_category (varchar) — classification of employee performance ('high_achiever', 'steady_performer', 'needs_attention')
    • salary_growth_rate (decimal) — percentage salary increase from first salary record to current
    • days_of_service (integer) — total days with the company
    • promotion_count (integer) — number of different titles held
  2. Analyze only current employees — focus on employees who currently have active salary records (to_date = '9999-01-01').

  3. Apply performance classification rules:

    • High achievers: Salary growth rate > 40% AND more than 1 title held
    • Needs attention: Salary growth rate < 15% AND more than 3650 days of service (10 years)
    • Steady performers: All other current employees (default category)
  4. Create the department salary analysis table — build a table called department_salary_analysis in the employees schema with:

    • department_name (varchar) — the department name
    • avg_current_salary (decimal) — average current salary in the department (only current employees)
    • employee_count (integer) — total current employees in the department
    • salary_range_spread (integer) — difference between max and min salary (current employees only)
  5. Calculate salary equity metrics — populate the department table with current salary statistics for active employees only to identify potential pay equity issues across departments.

The analysis should help leadership make informed decisions about promotions, salary adjustments, and talent retention strategies.



Verify

*.py
Python
"""
Verification script for PostgreSQL Task 1: Employee Performance Analysis
"""

import os
import sys
import psycopg2
from decimal import Decimal

def rows_match(actual_row, expected_row):
    """
    Compare two rows with appropriate tolerance.
    For Decimal types: allows 0.1 tolerance
    For other types: requires exact match
    """
    if len(actual_row) != len(expected_row):
        return False
    
    for actual, expected in zip(actual_row, expected_row):
        if isinstance(actual, Decimal) and isinstance(expected, Decimal):
            if abs(float(actual) - float(expected)) > 0.1:
                return False
        elif actual != expected:
            return False
    
    return True

def get_connection_params() -> dict:
    """Get database connection parameters."""
    return {
        "host": os.getenv("POSTGRES_HOST", "localhost"),
        "port": int(os.getenv("POSTGRES_PORT", 5432)),
        "database": os.getenv("POSTGRES_DATABASE"),
        "user": os.getenv("POSTGRES_USERNAME"),
        "password": os.getenv("POSTGRES_PASSWORD")
    }

def verify_performance_results(conn) -> bool:
    """Verify the employee performance analysis results."""
    with conn.cursor() as cur:
        # Get actual results from the created table
        cur.execute("""
            SELECT employee_id, performance_category, salary_growth_rate, 
                   days_of_service, promotion_count
            FROM employees.employee_performance_analysis 
            ORDER BY employee_id
        """)
        actual_results = cur.fetchall()
        
        # Execute ground truth query - use first salary record as starting salary
        cur.execute("""
            WITH current_salary AS (
            SELECT employee_id, amount AS current_amount
            FROM (
                SELECT s.*,
                    ROW_NUMBER() OVER (PARTITION BY s.employee_id
                                        ORDER BY s.from_date DESC, s.amount DESC) AS rn
                FROM employees.salary s
                WHERE s.to_date = DATE '9999-01-01'
            ) x
            WHERE rn = 1
            ),
            first_salary AS (
            SELECT employee_id, amount AS first_amount
            FROM (
                SELECT s.*,
                    ROW_NUMBER() OVER (PARTITION BY s.employee_id
                                        ORDER BY s.from_date ASC, s.amount ASC) AS rn
                FROM employees.salary s
            ) x
            WHERE rn = 1
            ),
            title_counts AS (
            SELECT t.employee_id, COUNT(DISTINCT t.title) AS promotion_count
            FROM employees.title t
            GROUP BY t.employee_id
            ),
            base AS (
            SELECT e.id AS employee_id,
                    e.hire_date,
                    cs.current_amount,
                    fs.first_amount,
                    COALESCE(tc.promotion_count, 0) AS promotion_count
            FROM employees.employee e
            JOIN current_salary cs ON cs.employee_id = e.id
            JOIN first_salary  fs ON fs.employee_id = e.id
            LEFT JOIN title_counts tc ON tc.employee_id = e.id
            ),
            scored AS (
            SELECT
                employee_id,
                ((current_amount - first_amount) / NULLIF(first_amount, 0)::NUMERIC) * 100 AS salary_growth_rate,
                (CURRENT_DATE - hire_date)::INTEGER AS days_of_service,
                promotion_count
            FROM base
            )
            SELECT
            s.employee_id,
            CASE
                WHEN s.salary_growth_rate > 40 AND s.promotion_count > 1 THEN 'high_achiever'
                WHEN s.salary_growth_rate < 15 AND s.days_of_service > 3650 THEN 'needs_attention'
                ELSE 'steady_performer'
            END AS performance_category,
            s.salary_growth_rate,
            s.days_of_service,
            s.promotion_count AS promotion_count
            FROM scored s
            ORDER BY s.employee_id;
        """)
        expected_results = cur.fetchall()

        if len(actual_results) != len(expected_results):
            print(f"❌ Expected {len(expected_results)} performance results, got {len(actual_results)}")
            return False

        mismatches = 0
        for i, (actual, expected) in enumerate(zip(actual_results, expected_results)):
            if not rows_match(actual, expected):
                if mismatches < 5:  # Only show first 5 mismatches
                    print(f"❌ Row {i+1} mismatch: expected {expected}, got {actual}")
                mismatches += 1

        if mismatches > 0:
            print(f"❌ Total mismatches: {mismatches}")
            return False

        print(f"✅ Employee performance results are correct ({len(actual_results)} records)")
        return True

def verify_department_results(conn) -> bool:
    """Verify the department salary analysis results."""
    with conn.cursor() as cur:
        # Get actual results from the created table
        cur.execute("""
            SELECT department_name, avg_current_salary, employee_count, salary_range_spread
            FROM employees.department_salary_analysis
            ORDER BY department_name
        """)
        actual_results = cur.fetchall()

        # Execute ground truth query
        cur.execute("""
            WITH current_salary AS (
            SELECT employee_id, amount
            FROM (
                SELECT s.*,
                    ROW_NUMBER() OVER (PARTITION BY s.employee_id
                                        ORDER BY s.from_date DESC, s.amount DESC) AS rn
                FROM employees.salary s
                WHERE s.to_date = DATE '9999-01-01'
            ) x
            WHERE rn = 1
            ),
            current_dept AS (
            SELECT DISTINCT de.employee_id, de.department_id
            FROM employees.department_employee de
            WHERE de.to_date = DATE '9999-01-01'
            )
            SELECT 
            d.dept_name AS department_name,
            AVG(cs.amount)::DECIMAL AS avg_current_salary,
            COUNT(DISTINCT cd.employee_id) AS employee_count,
            (MAX(cs.amount) - MIN(cs.amount)) AS salary_range_spread
            FROM employees.department d
            JOIN current_dept cd ON cd.department_id = d.id
            JOIN current_salary cs ON cs.employee_id = cd.employee_id
            GROUP BY d.id, d.dept_name
            ORDER BY d.dept_name;
        """)
        expected_results = cur.fetchall()

        if len(actual_results) != len(expected_results):
            print(f"❌ Expected {len(expected_results)} department results, got {len(actual_results)}")
            return False

        mismatches = 0
        for i, (actual, expected) in enumerate(zip(actual_results, expected_results)):
            if not rows_match(actual, expected):
                print(f"❌ Row {i+1} mismatch: expected {expected}, got {actual}")
                mismatches += 1

        if mismatches > 0:
            print(f"❌ Total mismatches: {mismatches}")
            return False

        print(f"✅ Department salary results are correct ({len(actual_results)} records)")
        return True

def main():
    """Main verification function."""
    print("=" * 50)

    # Get connection parameters
    conn_params = get_connection_params()

    if not conn_params["database"]:
        print("❌ No database specified")
        sys.exit(1)

    try:
        # Connect to database
        conn = psycopg2.connect(**conn_params)

        # Verify results
        success = verify_performance_results(conn) and verify_department_results(conn)

        conn.close()

        if success:
            print("\n🎉 Task verification: PASS")
            sys.exit(0)
        else:
            print("\n❌ Task verification: FAIL")
            sys.exit(1)

    except psycopg2.Error as e:
        print(f"❌ Database error: {e}")
        sys.exit(1)
    except Exception as e:
        print(f"❌ Verification error: {e}")
        sys.exit(1)

if __name__ == "__main__":
    main()