🧠
Using DENSE_RANK() Window Function
💡 Window functions like DENSE_RANK provide a powerful and elegant way to rank rows and handle duplicates correctly. This approach is optimal and widely supported in modern SQL.
Intuition
Assign ranks to salaries in descending order, with ties getting the same rank. Then select the salary with rank 2.
Algorithm
- Use DENSE_RANK() over salaries ordered descending to assign ranks.
- Filter rows where rank equals 2.
- Select the salary from these rows.
- Return NULL if no such row exists.
💡 This approach handles duplicates naturally and is efficient with indexing.
import sqlite3
conn = sqlite3.connect(':memory:')
cursor = conn.cursor()
cursor.execute('CREATE TABLE Employee(Id INTEGER, Salary INTEGER)')
cursor.executemany('INSERT INTO Employee VALUES (?, ?)', [(1, 100), (2, 200), (3, 300), (4, 300)])
query = '''
SELECT Salary FROM (
SELECT Salary, DENSE_RANK() OVER (ORDER BY Salary DESC) AS rnk
FROM Employee
) WHERE rnk = 2
'''
cursor.execute(query)
result = cursor.fetchone()
print(result[0] if result else 'NULL')
conn.close()
Line Notes
cursor.execute('CREATE TABLE Employee(Id INTEGER, Salary INTEGER)')Create Employee table to hold employee salary data.
cursor.executemany('INSERT INTO Employee VALUES (?, ?)')Insert sample data including duplicate salaries to test ranking.
DENSE_RANK() OVER (ORDER BY Salary DESC)Assign ranks to salaries in descending order, with ties sharing the same rank.
WHERE rnk = 2Filter to select only the second highest salary rank.
import java.sql.*;
public class SecondHighestSalaryDenseRank {
public static void main(String[] args) throws Exception {
Connection conn = DriverManager.getConnection("jdbc:sqlite::memory:");
Statement stmt = conn.createStatement();
stmt.execute("CREATE TABLE Employee(Id INTEGER, Salary INTEGER)");
stmt.execute("INSERT INTO Employee VALUES (1, 100), (2, 200), (3, 300), (4, 300)");
String query = "SELECT Salary FROM (SELECT Salary, DENSE_RANK() OVER (ORDER BY Salary DESC) AS rnk FROM Employee) WHERE rnk = 2";
ResultSet rs = stmt.executeQuery(query);
if (rs.next()) {
System.out.println(rs.getInt("Salary"));
} else {
System.out.println("NULL");
}
rs.close();
stmt.close();
conn.close();
}
}
Line Notes
Connection conn = DriverManager.getConnectionCreate in-memory SQLite connection for testing.
stmt.execute("CREATE TABLE EmployeeCreate Employee table schema.
DENSE_RANK() OVER (ORDER BY Salary DESC)Assign ranks to salaries with ties sharing the same rank.
WHERE rnk = 2Filter to get the second highest salary rank.
#include <iostream>
#include <sqlite3.h>
int main() {
sqlite3 *db;
sqlite3_open(":memory:", &db);
char *errMsg = nullptr;
sqlite3_exec(db, "CREATE TABLE Employee(Id INTEGER, Salary INTEGER);", nullptr, nullptr, &errMsg);
sqlite3_exec(db, "INSERT INTO Employee VALUES (1, 100), (2, 200), (3, 300), (4, 300);", nullptr, nullptr, &errMsg);
const char *sql = "SELECT Salary FROM (SELECT Salary, DENSE_RANK() OVER (ORDER BY Salary DESC) AS rnk FROM Employee) WHERE rnk = 2;";
sqlite3_stmt *stmt;
sqlite3_prepare_v2(db, sql, -1, &stmt, nullptr);
if (sqlite3_step(stmt) == SQLITE_ROW) {
std::cout << sqlite3_column_int(stmt, 0) << std::endl;
} else {
std::cout << "NULL" << std::endl;
}
sqlite3_finalize(stmt);
sqlite3_close(db);
return 0;
}
Line Notes
sqlite3_open(":memory:", &db);Open in-memory SQLite database for testing.
sqlite3_exec(db, "CREATE TABLE EmployeeCreate Employee table schema.
DENSE_RANK() OVER (ORDER BY Salary DESC)Assign ranks to salaries with ties sharing the same rank.
WHERE rnk = 2Filter to select the second highest salary rank.
const sqlite3 = require('sqlite3').verbose();
const db = new sqlite3.Database(':memory:');
db.serialize(() => {
db.run('CREATE TABLE Employee(Id INTEGER, Salary INTEGER)');
db.run('INSERT INTO Employee VALUES (1, 100), (2, 200), (3, 300), (4, 300)');
const query = `
SELECT Salary FROM (
SELECT Salary, DENSE_RANK() OVER (ORDER BY Salary DESC) AS rnk
FROM Employee
) WHERE rnk = 2
`;
db.get(query, (err, row) => {
if (err) throw err;
console.log(row ? row.Salary : 'NULL');
});
});
db.close();
Line Notes
db.run('CREATE TABLE EmployeeCreate Employee table schema.
db.run('INSERT INTO Employee VALUESInsert sample data including duplicates to test ranking.
DENSE_RANK() OVER (ORDER BY Salary DESC)Assign ranks to salaries with ties sharing the same rank.
WHERE rnk = 2Filter to select the second highest salary rank.
TimeO(n log n) due to sorting in window function
SpaceO(n) for window function state
Window functions require sorting and maintaining rank state, but handle duplicates elegantly.
💡 For 100,000 employees, this is efficient and scalable with proper indexing.
Interview Verdict: Accepted
This is the preferred approach in modern SQL for clarity and correctness.