Companies Whose Average Employee Salary Is Above 40,000

Read the full interview experience this question came from →

Quick Overview

Write a PostgreSQL query over employee, company and salary tables that returns the names of companies whose employees' average salary is strictly greater than 40,000. It tests joining and grouping, filtering on an aggregate, exact averages at the threshold boundary, and stable ordering by company id.

Companies Whose Average Employee Salary Is Above 40,000

Company: Verisk

Role: Data Scientist

Category: Data Manipulation (SQL/Python)

Difficulty: easy

Interview Round: Online Assessment

A company directory keeps its employees, companies and salaries in three tables. Write a query that returns the name of every company whose employees' average salary is strictly greater than 40,000. The report names the three tables (`EMPLOYEE`, `COMPANY` and `SALARY`), the strict 40,000 threshold and the company name as the output, and suggests ordering by company id so that the output order is stable. It does not list the tables' columns, so this version fixes the schema below, with exactly one salary row per employee. ### Input Table(s) **`employee`**: one row per employee. | Column | Type | Meaning | | --- | --- | --- | | `id` | INTEGER | Primary key; unique per employee | | `name` | TEXT | Employee name | **`company`**: one row per company. | Column | Type | Meaning | | --- | --- | --- | | `id` | INTEGER | Primary key; unique per company | | `name` | TEXT | Company name; two different companies may share a name | **`salary`**: one row per employee. | Column | Type | Meaning | | --- | --- | --- | | `employee_id` | INTEGER | Primary key; references `employee.id` | | `company_id` | INTEGER | References `company.id`; the company the employee works for | | `salary` | INTEGER | The employee's salary, a positive whole number | ### Output Contract Write one read-only PostgreSQL query (`SELECT`, optionally with `WITH`) that returns one row per qualifying company, with exactly this column: | Column | Type | Meaning | | --- | --- | --- | | `name` | text | The qualifying company's `company.name` | A company qualifies when the average of its employees' salaries is strictly greater than 40,000. Order the rows by company `id` ascending. The id is not an output column, but it is unique, so the order is fully determined. The result may have zero rows. ### Example `employee`: | id | name | | --- | --- | | 1 | Avery | | 2 | Blake | | 3 | Casey | | 4 | Devon | | 5 | Emery | | 6 | Finley | | 7 | Gray | `company`: | id | name | | --- | --- | | 1 | Northwind | | 2 | Harbor Mutual | | 3 | Summit Data | | 4 | Northwind | | 5 | Lakeside Labs | `salary`: | employee_id | company_id | salary | | --- | --- | --- | | 1 | 1 | 52000 | | 2 | 1 | 30000 | | 3 | 2 | 40000 | | 4 | 2 | 40000 | | 5 | 3 | 40000 | | 6 | 3 | 40001 | | 7 | 4 | 45000 | Expected result: | name | | --- | | Northwind | | Summit Data | | Northwind | - Northwind (id 1): salaries 52,000 and 30,000 average 41,000, which is above the threshold, so it is returned. - Harbor Mutual (id 2): the average is exactly 40,000, which is not strictly greater, so it is excluded. - Summit Data (id 3): the average is 40,000.5, which is strictly greater, so it is returned. - Northwind (id 4): a different company that shares a name with id 1. Its only employee earns 45,000, so it is returned as its own row. - Lakeside Labs (id 5): no employees, so it has no average and is excluded. The rows appear in company id order: 1, 3, 4. ### Constraints and Clarifications - No column contains NULL. `salary.employee_id` is unique and every employee appears in `salary` exactly once, so each employee has one salary and works for one company. Every `employee_id` and `company_id` in `salary` exists in its parent table. - A company's average is the exact arithmetic mean of its employees' salaries, with no rounding or truncation before the comparison: an average of 40,000.5 qualifies, and an average of exactly 40,000 does not. - A company with no rows in `salary` has no employees and no average, and is not returned. - Companies that share a name are evaluated separately, and each qualifying one appears as its own row. - If no company qualifies, or the tables are empty, the result has no rows. ```hint Test the boundary Before submitting, check what your query returns for a company whose average is exactly 40,000 and for one whose average is 40,000.5. ```

Overview: Write a PostgreSQL query over employee, company and salary tables that returns the names of companies whose employees' average salary is strictly greater than 40,000. It tests joining and grouping, filtering on an aggregate, exact averages at the threshold boundary, and stable ordering by company id.

Read the full Verisk Data Scientist interview experience this question came from

Verisk logo
Verisk
Nov 12, 2026
easyData ScientistOnline AssessmentData Manipulation (SQL/Python)
0
0

A company directory keeps its employees, companies and salaries in three tables. Write a query that returns the name of every company whose employees' average salary is strictly greater than 40,000.

The report names the three tables (EMPLOYEE, COMPANY and SALARY), the strict 40,000 threshold and the company name as the output, and suggests ordering by company id so that the output order is stable. It does not list the tables' columns, so this version fixes the schema below, with exactly one salary row per employee.

Input Table(s)

employee: one row per employee.

ColumnTypeMeaning
idINTEGERPrimary key; unique per employee
nameTEXTEmployee name

company: one row per company.

ColumnTypeMeaning
idINTEGERPrimary key; unique per company
nameTEXTCompany name; two different companies may share a name

salary: one row per employee.

ColumnTypeMeaning
employee_idINTEGERPrimary key; references employee.id
company_idINTEGERReferences company.id; the company the employee works for
salaryINTEGERThe employee's salary, a positive whole number

Output Contract

Write one read-only PostgreSQL query (SELECT, optionally with WITH) that returns one row per qualifying company, with exactly this column:

ColumnTypeMeaning
nametextThe qualifying company's company.name

A company qualifies when the average of its employees' salaries is strictly greater than 40,000. Order the rows by company id ascending. The id is not an output column, but it is unique, so the order is fully determined. The result may have zero rows.

Example

employee:

idname
1Avery
2Blake
3Casey
4Devon
5Emery
6Finley
7Gray

company:

idname
1Northwind
2Harbor Mutual
3Summit Data
4Northwind
5Lakeside Labs

salary:

employee_idcompany_idsalary
1152000
2130000
3240000
4240000
5340000
6340001
7445000

Expected result:

name
Northwind
Summit Data
Northwind
  • Northwind (id 1): salaries 52,000 and 30,000 average 41,000, which is above the threshold, so it is returned.
  • Harbor Mutual (id 2): the average is exactly 40,000, which is not strictly greater, so it is excluded.
  • Summit Data (id 3): the average is 40,000.5, which is strictly greater, so it is returned.
  • Northwind (id 4): a different company that shares a name with id 1. Its only employee earns 45,000, so it is returned as its own row.
  • Lakeside Labs (id 5): no employees, so it has no average and is excluded.

The rows appear in company id order: 1, 3, 4.

Constraints and Clarifications

  • No column contains NULL. salary.employee_id is unique and every employee appears in salary exactly once, so each employee has one salary and works for one company. Every employee_id and company_id in salary exists in its parent table.
  • A company's average is the exact arithmetic mean of its employees' salaries, with no rounding or truncation before the comparison: an average of 40,000.5 qualifies, and an average of exactly 40,000 does not.
  • A company with no rows in salary has no employees and no average, and is not returned.
  • Companies that share a name are evaluated separately, and each qualifying one appears as its own row.
  • If no company qualifies, or the tables are empty, the result has no rows.