Top 60 MS SQL Server Interview Questions (2026)

The 60 MS SQL Server questions interviewers actually ask, with direct answers, runnable T-SQL, and what the interviewer is listening for. Grouped for freshers, intermediate, and experienced rounds.

60 questions with answers

What Is MS SQL Server?

Key Takeaways

  • MS SQL Server is Microsoft's relational database engine, queried and programmed through the T-SQL dialect.
  • It bundles the database engine with tools like SSMS, and services for reporting, integration, and analysis.
  • Interviews test how well you understand indexes, transactions, isolation levels, and query plans, not just SELECT syntax.
  • This page is a question bank: work your tier first, read one tier up, and say answers out loud because delivery is evaluated too.

Microsoft SQL Server is a relational database management system built by Microsoft, first released in 1989 and now shipping in editions from the free Express and Developer builds up to Enterprise. It stores data in tables with enforced relationships, and you talk to it through Transact-SQL (T-SQL), Microsoft's extension of standard SQL that adds procedural constructs like variables, control flow, and stored procedures. According to Microsoft's official documentation, SQL Server is a database engine paired with a set of services for reporting, integration, and analytics, so the product is broader than the query language alone. In interviews, SQL Server questions probe how indexes, transactions, isolation levels, and execution plans actually behave, not memorized syntax. This page collects the 60 questions that come up most, each with a direct answer and runnable T-SQL. If you're still building fundamentals, Microsoft Learn is the canonical path; increasingly the first database round is a live AI coding interview, so pair this bank with our AI interview preparation guides for the format side.

60Questions with answers on this page
3Difficulty tiers: freshers, intermediate, experienced
T-SQLThe dialect SQL Server uses for queries and procedures
45-60 minTypical length of a SQL Server technical round

Watch: SQL Server Tutorial For Beginners

Video: SQL Server Tutorial For Beginners (edureka!, YouTube)

Test yourself and earn a certificate

10 quick questions. Score 70%+ to download your MS SQL Server certificate.

Jump to quiz

All Questions on This Page

60 questions
MS SQL Server Interview Questions for Freshers
  1. 1. What is MS SQL Server?
  2. 2. What is T-SQL and how does it differ from standard SQL?
  3. 3. What is the difference between a primary key and a unique key?
  4. 4. What is a foreign key?
  5. 5. What are the types of JOINs in SQL Server?
  6. 6. What is the difference between WHERE and HAVING?
  7. 7. What is the difference between DELETE, TRUNCATE, and DROP?
  8. 8. What is the difference between CHAR, VARCHAR, and NVARCHAR?
  9. 9. What is an index in SQL Server?
  10. 10. What is the difference between a clustered and a nonclustered index?
  11. 11. What is normalization?
  12. 12. What is the difference between DDL, DML, and DCL commands?
  13. 13. How does SQL Server handle NULL, and how do you test for it?
  14. 14. What are aggregate functions and how does GROUP BY work?
  15. 15. What does the DISTINCT keyword do?
  16. 16. What is the difference between UNION and UNION ALL?
  17. 17. What does the TOP clause do?
  18. 18. What do the BETWEEN, IN, and LIKE operators do?
  19. 19. What is a view?
  20. 20. What is an IDENTITY column?
  21. 21. What are common date and time functions in T-SQL?
  22. 22. What is SQL injection and how do you prevent it?
MS SQL Server Intermediate Interview Questions
  1. 23. What are the ACID properties of a transaction?
  2. 24. What are the transaction isolation levels in SQL Server?
  3. 25. What is the difference between a stored procedure and a function?
  4. 26. What is a CTE (Common Table Expression)?
  5. 27. What are window functions and how do ROW_NUMBER, RANK, and DENSE_RANK differ?
  6. 28. What is the difference between a correlated and a non-correlated subquery?
  7. 29. What is the difference between a temp table and a table variable?
  8. 30. In what logical order does SQL Server process a SELECT query?
  9. 31. What is a covering index?
  10. 32. What does the MERGE statement do?
  11. 33. How does error handling work with TRY CATCH in T-SQL?
  12. 34. What is a deadlock and how do you resolve one?
  13. 35. What do PIVOT and UNPIVOT do?
  14. 36. How does the CASE expression work?
  15. 37. What is the difference between ISNULL and COALESCE?
  16. 38. What is a trigger?
  17. 39. What is the difference between a scalar function and a table-valued function?
  18. 40. How would you find duplicate rows in a table?
  19. 41. How do you find the second highest salary?
  20. 42. How do you paginate results in SQL Server?
  21. 43. What is the difference between the CHAR functions LEN and DATALENGTH?
MS SQL Server Interview Questions for Experienced Engineers
  1. 44. How do you read a SQL Server execution plan to find a slow query?
  2. 45. What is parameter sniffing and when does it cause problems?
  3. 46. How do you choose a good clustered index key?
  4. 47. What are statistics, and how do they affect query plans?
  5. 48. What is the difference between locking and blocking, and how do you diagnose blocking?
  6. 49. What is lock escalation?
  7. 50. What is an indexed view and when is it worth it?
  8. 51. What is table partitioning and what problem does it solve?
  9. 52. How does the transaction log work, and why can it grow uncontrollably?
  10. 53. What are the recovery models in SQL Server?
  11. 54. What is index fragmentation and how do you manage it?
  12. 55. What is a columnstore index and when would you use one?
  13. 56. How do Always On Availability Groups provide high availability?
  14. 57. Why can scalar user-defined functions hurt performance, and what changed?
  15. 58. How does optimistic concurrency differ from pessimistic concurrency in SQL Server?
  16. 59. Design question: how would you design an audit trail for a busy transactional database?
  17. 60. How do you approach optimizing a query that suddenly got slow overnight?

MS SQL Server Interview Questions for Freshers

Freshers22 questions

The fundamentals every entry-level round checks. If any answer here surprises you, that's your study list.

Q1. What is MS SQL Server?

MS SQL Server is Microsoft's relational database management system. It stores data in tables with defined relationships and lets you query and modify that data through T-SQL, Microsoft's SQL dialect.

It's more than a query engine: the product bundles services for reporting, integration, and analytics, plus tools like SQL Server Management Studio. Editions run from the free Express and Developer builds up to Enterprise.

Key point: A one-line definition plus a mention of T-SQL and editions beats a memorized feature list. Interviewers open with this to hear how you organize an answer.

Watch a deeper explanation

Video: SQL Server Tutorial For Beginners (edureka!, YouTube)

Q2. What is T-SQL and how does it differ from standard SQL?

T-SQL (Transact-SQL) is Microsoft's extension of standard SQL. It keeps the standard SELECT, INSERT, UPDATE, and DELETE, then adds procedural features: variables, IF and WHILE control flow, error handling, and stored procedures.

So standard SQL is the shared query language, and T-SQL is what you actually write in SQL Server. Functions like ISNULL, TOP, and GETDATE are T-SQL specifics you won't find spelled the same way elsewhere.

sql
DECLARE @today DATE = GETDATE();

IF @today > '2026-01-01'
    SELECT TOP (5) name FROM Employees ORDER BY hired_on DESC;
ELSE
    SELECT 'no recent hires';

Key point: Naming one procedural feature (variables or TRY CATCH) proves you know T-SQL is more than dialect differences in SELECT.

Q3. What is the difference between a primary key and a unique key?

A primary key uniquely identifies each row and cannot contain NULL; a table has exactly one. A unique key also enforces uniqueness but allows a single NULL value, and a table can have several.

By default SQL Server backs a primary key with a clustered index and a unique constraint with a nonclustered index, though you can change that. Both prevent duplicate values in the columns they cover.

Primary keyUnique key
NULLs allowedNoYes, one
Per tableOneMany
Default indexClusteredNonclustered
PurposeRow identityEnforce uniqueness

Key point: The follow-up is usually about NULLs. Say the primary key rejects NULLs while a unique key permits exactly one.

Q4. What is a foreign key?

A foreign key is a column, or set of columns, that references the primary key of another table. It enforces referential integrity: you can't insert a value that has no matching parent row, and you can't orphan children by deleting a referenced parent.

It's how relationships between tables get enforced by the database instead of relying on application code to keep data consistent.

sql
CREATE TABLE Orders (
    order_id   INT PRIMARY KEY,
    customer_id INT NOT NULL,
    FOREIGN KEY (customer_id) REFERENCES Customers(customer_id)
);

Q5. What are the types of JOINs in SQL Server?

INNER JOIN returns only rows matching in both tables. LEFT JOIN keeps all left-table rows plus matches. RIGHT JOIN keeps all right-table rows plus matches. FULL OUTER JOIN keeps unmatched rows from both sides. CROSS JOIN produces every combination.

The unmatched side fills with NULLs in outer joins, which is exactly how you find rows that have no match: a LEFT JOIN with a WHERE that checks the right side IS NULL.

sql
-- customers who have never placed an order
SELECT c.name
FROM Customers c
LEFT JOIN Orders o ON o.customer_id = c.customer_id
WHERE o.order_id IS NULL;
JoinKeepsFills unmatched with
INNEROnly matchesNothing (dropped)
LEFTAll left rowsNULL on the right
RIGHTAll right rowsNULL on the left
FULL OUTERAll rows both sidesNULL on the empty side

Key point: The find-rows-with-no-match trick (LEFT JOIN plus IS NULL) is a favorite follow-up. Have it ready.

Watch a deeper explanation

Video: SQL Joins Explained (Socratica, YouTube)

Q6. What is the difference between WHERE and HAVING?

WHERE filters individual rows before grouping happens. HAVING filters groups after GROUP BY has aggregated them, so aggregate conditions like COUNT(*) > 5 belong in HAVING, not WHERE.

You can use both in one query: WHERE narrows the raw rows, GROUP BY buckets them, and HAVING keeps only the buckets you want.

sql
SELECT customer_id, COUNT(*) AS orders
FROM Orders
WHERE status = 'shipped'      -- filters rows first
GROUP BY customer_id
HAVING COUNT(*) > 5;           -- filters groups after

Key point: the key signal is the word 'aggregate'. HAVING exists because WHERE runs before aggregation and can't see COUNT or SUM.

Q7. What is the difference between DELETE, TRUNCATE, and DROP?

DELETE removes rows one at a time, accepts a WHERE clause, logs each deletion, and can be rolled back. TRUNCATE removes all rows by deallocating pages, is minimally logged, resets the identity seed, and is much faster but can't be filtered. DROP removes the entire table, structure included.

So DELETE is a data operation you can target, TRUNCATE is a fast full wipe, and DROP is a schema operation.

DELETETRUNCATEDROP
WHERE clauseYesNoNo
Resets identityNoYesN/A
Removes structureNoNoYes
LoggingFullMinimalMinimal

Key point: The reset-identity detail on TRUNCATE separates a memorized answer from real experience. Mention it.

Q8. What is the difference between CHAR, VARCHAR, and NVARCHAR?

CHAR is fixed length and pads with spaces, so CHAR(10) always uses ten characters. VARCHAR is variable length and stores only what you put in, up to the declared max. NVARCHAR is like VARCHAR but stores Unicode, using two bytes per character to hold any language.

Reach for VARCHAR when values vary in length, CHAR only for genuinely fixed-width codes, and NVARCHAR whenever the text can contain non-Latin characters.

Key point: The Unicode point on NVARCHAR is the one the question needs. It's the difference between storing English only and storing any language.

Q9. What is an index in SQL Server?

An index is a data structure that speeds up row lookups, much like a book's index points you to a page. Instead of scanning every row, SQL Server walks the index to find matching rows fast. Most SQL Server indexes are B-tree structures.

The trade-off: indexes speed up reads but slow down writes, because every insert, update, and delete has to maintain the index too. They also use disk space.

sql
CREATE NONCLUSTERED INDEX IX_Orders_CustomerId
ON Orders (customer_id);

Key point: Always The read-versus-write trade-off. Candidates who only say 'indexes make queries faster' miss half the answer.

Watch a deeper explanation

Video: SQL Index and Indexes in SQL (Socratica, YouTube)

Q10. What is the difference between a clustered and a nonclustered index?

A clustered index sorts and stores the table's rows in the index order, so the table IS the index. A table can have only one, since rows can be physically ordered just one way. A nonclustered index is a separate structure that points back to the rows, and a table can have many.

The primary key gets a clustered index by default. Nonclustered indexes carry the columns you search on plus a pointer to the actual row.

ClusteredNonclustered
Per tableOneMany
Stores rowsYes, in index orderNo, points to rows
Default onPrimary keyUnique constraint
AnalogyPhone book itselfIndex at the back

Key point: The one-clustered-index rule and the reason (physical row order) is the answer. State both.

Q11. What is normalization?

Normalization is organizing tables to reduce redundancy and prevent update anomalies. You split data into related tables so each fact lives in one place, then link them with keys. The common forms are 1NF (atomic values), 2NF (no partial dependency on part of a composite key), and 3NF (no dependency on non-key columns).

The payoff is consistency: change a customer's address once instead of in every order row. The cost is more joins at read time.

Key point: Interviewers often ask you to explain 3NF plainly. Say: every non-key column depends on the key, the whole key, and nothing but the key.

Q12. What is the difference between DDL, DML, and DCL commands?

DDL (Data Definition Language) defines structure: CREATE, ALTER, DROP, TRUNCATE. DML (Data Manipulation Language) changes data: SELECT, INSERT, UPDATE, DELETE. DCL (Data Control Language) manages permissions: GRANT and REVOKE.

There's also TCL (Transaction Control Language): COMMIT, ROLLBACK, and SAVE TRANSACTION, which control transaction boundaries.

Key point: Placing TRUNCATE under DDL, not DML, is a common trap. It deallocates pages rather than deleting rows, so it belongs with DDL.

Q13. How does SQL Server handle NULL, and how do you test for it?

NULL means unknown or missing, not zero or empty string. Any comparison with NULL using = or <> returns UNKNOWN, so those rows never match a WHERE filter. To test for NULL you must use IS NULL or IS NOT NULL.

ISNULL(col, replacement) substitutes a value when a column is NULL, and COALESCE returns the first non-NULL from a list.

sql
-- wrong: matches nothing
SELECT * FROM Employees WHERE manager_id = NULL;

-- right
SELECT * FROM Employees WHERE manager_id IS NULL;

SELECT ISNULL(bonus, 0) AS bonus FROM Employees;

Key point: The three-valued logic point (true, false, unknown) is what this question screens for. NULL comparisons return UNKNOWN.

Q14. What are aggregate functions and how does GROUP BY work?

Aggregate functions collapse many rows into one value: COUNT, SUM, AVG, MIN, and MAX. GROUP BY splits rows into buckets by one or more columns, then applies the aggregate to each bucket.

Every column in the SELECT that isn't inside an aggregate must appear in the GROUP BY, otherwise SQL Server raises an error.

sql
SELECT department, COUNT(*) AS headcount, AVG(salary) AS avg_salary
FROM Employees
GROUP BY department;

Q15. What does the DISTINCT keyword do?

DISTINCT removes duplicate rows from a result set, keeping one copy of each unique combination of the selected columns. It applies to the whole row the SELECT returns, not a single column.

It costs a sort or hash to find duplicates, so on large results it isn't free. Often a GROUP BY or a better join condition removes duplicates more cheaply.

sql
SELECT DISTINCT country FROM Customers;

-- distinct pairs, not just distinct city
SELECT DISTINCT country, city FROM Customers;

Q16. What is the difference between UNION and UNION ALL?

UNION combines the results of two queries and removes duplicate rows, which means it does a sort or hash to dedupe. UNION ALL combines them and keeps every row, duplicates included, so it's faster.

Use UNION ALL by default and only reach for UNION when you actually need duplicates gone. Both require the same number of columns with compatible types.

sql
SELECT city FROM Customers
UNION ALL
SELECT city FROM Suppliers;   -- keeps duplicates, faster

Key point: Say UNION ALL is faster because it skips the dedupe step. Reaching for UNION ALL by default indicates performance awareness.

Q17. What does the TOP clause do?

TOP limits how many rows a query returns. TOP (10) returns the first ten rows, and with an ORDER BY it returns the ten highest or lowest by that order. TOP (5) PERCENT returns a percentage of the result.

Without ORDER BY, which rows you get is arbitrary, so pair TOP with ORDER BY whenever the ranking matters. WITH TIES includes rows that tie with the last one.

sql
SELECT TOP (3) WITH TIES name, salary
FROM Employees
ORDER BY salary DESC;

Q18. What do the BETWEEN, IN, and LIKE operators do?

BETWEEN tests a range and is inclusive of both bounds. IN tests membership in a list of values. LIKE matches string patterns with wildcards: % for any run of characters and _ for a single character.

BETWEEN '2026-01-01' AND '2026-01-31' catches the whole range; IN (1, 2, 3) is shorthand for three OR conditions; LIKE 'A%' finds anything starting with A.

sql
SELECT * FROM Orders
WHERE total BETWEEN 100 AND 500
  AND status IN ('shipped', 'delivered')
  AND name LIKE 'A%';

Q19. What is a view?

A view is a saved query that behaves like a virtual table. It stores no data itself; when you select from it, SQL Server runs the underlying query. Views simplify complex joins, hide columns, and give a stable interface even as base tables change.

You can read from most views normally. Updating through a view works only when the view maps cleanly to one base table without aggregation.

sql
CREATE VIEW ActiveCustomers AS
SELECT customer_id, name, email
FROM Customers
WHERE is_active = 1;

SELECT * FROM ActiveCustomers;

Q20. What is an IDENTITY column?

An IDENTITY column auto-generates increasing numbers as rows are inserted, so you don't supply the value yourself. IDENTITY(1,1) starts at 1 and increments by 1, which is the usual surrogate primary key pattern.

SCOPE_IDENTITY() returns the last identity value your statement generated. TRUNCATE resets the seed; DELETE does not, so gaps can appear after deletions.

sql
CREATE TABLE Products (
    product_id INT IDENTITY(1,1) PRIMARY KEY,
    name NVARCHAR(100)
);

INSERT INTO Products (name) VALUES ('Keyboard');
SELECT SCOPE_IDENTITY();   -- the new product_id

Q21. What are common date and time functions in T-SQL?

GETDATE() returns the current date and time. DATEADD(unit, n, date) shifts a date. DATEDIFF(unit, start, end) returns the difference between two dates. DATEPART extracts a piece like year or month, and FORMAT or CONVERT reshape output.

Store dates in DATE, DATETIME2, or DATETIMEOFFSET types rather than strings, so comparisons and math work correctly.

sql
SELECT GETDATE() AS now,
       DATEADD(DAY, 7, GETDATE()) AS next_week,
       DATEDIFF(DAY, hired_on, GETDATE()) AS days_employed
FROM Employees;

Q22. What is SQL injection and how do you prevent it?

SQL injection is when user input is concatenated into a query so an attacker can inject their own SQL, reading or destroying data. Building queries by gluing strings together is what opens the hole.

The fix is parameterized queries or stored procedures with parameters, so input is treated as data, never as executable SQL. Never build a query by concatenating raw user input.

sql
-- parameterized: input can't change the query shape
EXEC sp_executesql
    N'SELECT * FROM Users WHERE email = @email',
    N'@email NVARCHAR(200)',
    @email = @userInput;

Key point: Say the word 'parameterized'. the key point is that input becomes data, not SQL, not just 'sanitize input'.

Back to question list

MS SQL Server Intermediate Interview Questions

Intermediate21 questions

For candidates with working experience: query mechanics, transactions, and the questions that separate users from understanders.

Q23. What are the ACID properties of a transaction?

ACID is Atomicity, Consistency, Isolation, Durability. Atomicity means a transaction is all-or-nothing. Consistency means it moves the database from one valid state to another. Isolation means concurrent transactions don't see each other's half-done work. Durability means once committed, changes survive a crash.

SQL Server guarantees these through the transaction log and locking. Wrapping related writes in BEGIN TRANSACTION and COMMIT is how you get atomicity across multiple statements.

sql
BEGIN TRANSACTION;
    UPDATE Accounts SET balance = balance - 100 WHERE id = 1;
    UPDATE Accounts SET balance = balance + 100 WHERE id = 2;
COMMIT;   -- both succeed or, on error, ROLLBACK undoes both

Key point: Give a one-line meaning per letter, then atomicity maps to the money-transfer example. That structure works well.

Watch a deeper explanation

Video: Relational Database ACID Transactions Explained by Example (Hussein Nasser, YouTube)

Q24. What are the transaction isolation levels in SQL Server?

SQL Server offers READ UNCOMMITTED (allows dirty reads), READ COMMITTED (the default, no dirty reads), REPEATABLE READ (no non-repeatable reads), SERIALIZABLE (no phantom reads, strictest), and SNAPSHOT (row versioning so readers don't block writers).

Higher isolation means fewer anomalies but more blocking. SNAPSHOT and READ COMMITTED SNAPSHOT use versioning to give consistency without readers holding locks, which is why many teams enable them.

LevelDirty readNon-repeatable readPhantom
READ UNCOMMITTEDPossiblePossiblePossible
READ COMMITTEDNoPossiblePossible
REPEATABLE READNoNoPossible
SERIALIZABLENoNoNo

Key point: Know which anomaly each level prevents. The table above is exactly what a strong candidate can reproduce on a whiteboard.

Q25. What is the difference between a stored procedure and a function?

A stored procedure is a named batch of T-SQL that can modify data, return multiple result sets, use output parameters, and handle transactions. A function returns a single value or a table and must be side-effect free, so it can't change data and can be used inside a query.

The practical split: use a function when you need a value inside a SELECT or WHERE, and a procedure when you're performing an action like inserting or orchestrating logic.

sql
CREATE FUNCTION dbo.FullName(@first NVARCHAR(50), @last NVARCHAR(50))
RETURNS NVARCHAR(101)
AS
BEGIN
    RETURN @first + ' ' + @last;
END;

SELECT dbo.FullName(first_name, last_name) FROM Employees;
Stored procedureFunction
Modifies dataYesNo
Used inside a SELECTNoYes
ReturnsZero or many result setsOne value or a table
TransactionsAllowedNot allowed

Key point: The 'can it be called inside a query?' distinction is the crisp answer. Functions can, procedures can't.

Q26. What is a CTE (Common Table Expression)?

A CTE is a named temporary result set defined with WITH that exists only for the query that follows it. It makes complex queries readable by naming intermediate steps instead of nesting subqueries.

A recursive CTE references itself, which is how you walk hierarchies like an org chart or a category tree without a loop.

sql
WITH DirectReports AS (
    SELECT employee_id, manager_id, name, 0 AS lvl
    FROM Employees WHERE manager_id IS NULL
    UNION ALL
    SELECT e.employee_id, e.manager_id, e.name, d.lvl + 1
    FROM Employees e
    JOIN DirectReports d ON e.manager_id = d.employee_id
)
SELECT * FROM DirectReports;

Key point: Recursion is the follow-up. Have the org-chart example ready to show a recursive CTE walking a hierarchy.

Q27. What are window functions and how do ROW_NUMBER, RANK, and DENSE_RANK differ?

Window functions compute a value across a set of rows related to the current row, without collapsing them the way GROUP BY does. The OVER clause defines the window with PARTITION BY and ORDER BY.

ROW_NUMBER assigns a unique sequential number. RANK gives tied rows the same rank but skips the next numbers. DENSE_RANK gives ties the same rank with no gaps. All three keep every row in the output.

sql
SELECT name, department, salary,
       ROW_NUMBER() OVER (PARTITION BY department ORDER BY salary DESC) AS rn,
       RANK()       OVER (PARTITION BY department ORDER BY salary DESC) AS rnk,
       DENSE_RANK() OVER (PARTITION BY department ORDER BY salary DESC) AS drnk
FROM Employees;
SalariesROW_NUMBERRANKDENSE_RANK
100111
100211
90332
80443

Key point: The tie behavior is the whole question. RANK skips, DENSE_RANK doesn't, ROW_NUMBER is always unique.

Q28. What is the difference between a correlated and a non-correlated subquery?

A non-correlated subquery runs once, independent of the outer query, and its result feeds the outer query. A correlated subquery references a column from the outer query, so it runs once per outer row, which can be slow.

Correlated subqueries are often rewritable as joins or window functions that the optimizer handles better. Recognizing when to rewrite one is what this question checks.

sql
-- correlated: runs per outer row
SELECT name FROM Employees e
WHERE salary > (SELECT AVG(salary) FROM Employees
                WHERE department = e.department);

Q29. What is the difference between a temp table and a table variable?

A temp table (#temp) lives in tempdb, supports indexes and statistics, and can be altered after creation, which makes it better for large intermediate sets. A table variable (@table) is scoped to the batch, holds no column statistics, and suits small result sets.

The statistics difference matters: the optimizer often assumes a table variable holds one row, which can produce bad plans on larger data. For big sets, reach for a temp table.

Temp table (#t)Table variable (@t)
StatisticsYesNo (assumes 1 row)
IndexesFull supportLimited
ScopeSessionBatch
Best forLarge setsSmall sets

Key point: The statistics point is The production-ready answer. Table variables mislead the optimizer on row count, so plans degrade on big data.

Q30. In what logical order does SQL Server process a SELECT query?

Logically the engine processes FROM and JOIN first, then WHERE, then GROUP BY, then HAVING, then SELECT, then DISTINCT, then ORDER BY, and finally TOP or OFFSET. Not the written order.

This order explains why you can't use a SELECT alias in WHERE (WHERE runs before SELECT) but can in ORDER BY (which runs after SELECT), and why HAVING sees aggregates that WHERE can't.

  • FROM / JOIN: assemble the source rows
  • WHERE: filter individual rows
  • GROUP BY: bucket rows
  • HAVING: filter buckets
  • SELECT: compute columns and aliases
  • ORDER BY: sort the final result

Key point: This single concept answers three follow-ups at once: alias scope, WHERE versus HAVING, and why DISTINCT sees computed columns.

Q31. What is a covering index?

A covering index contains every column a query needs, either in the key or in INCLUDE columns, so SQL Server answers the query from the index alone without touching the table. That avoids the extra key lookup into the clustered index.

You put the columns you filter and join on in the key, and the columns you only return in INCLUDE. It's one of the highest-impact tuning moves for a hot read query.

sql
CREATE NONCLUSTERED INDEX IX_Orders_Cover
ON Orders (customer_id, status)     -- searched columns
INCLUDE (order_date, total);        -- returned columns

Key point: INCLUDE columns and the avoided key lookup is what matters.

Q32. What does the MERGE statement do?

MERGE performs an upsert: it compares a source to a target and, in one statement, inserts rows that are new, updates rows that match, and optionally deletes rows that no longer exist in the source. It's the classic tool for syncing a staging table into a target.

It reduces several separate statements to one, though on high-concurrency workloads some teams prefer explicit INSERT and UPDATE for predictability.

sql
MERGE INTO Products AS tgt
USING Staging AS src ON tgt.sku = src.sku
WHEN MATCHED THEN
    UPDATE SET tgt.price = src.price
WHEN NOT MATCHED THEN
    INSERT (sku, price) VALUES (src.sku, src.price);

Q33. How does error handling work with TRY CATCH in T-SQL?

You wrap risky statements in BEGIN TRY and BEGIN CATCH. If an error fires in the TRY block, control jumps to CATCH, where functions like ERROR_MESSAGE and ERROR_NUMBER describe what went wrong. You typically ROLLBACK there and optionally re-raise with THROW.

Combined with transactions, TRY CATCH is how you make a multi-statement operation atomic: commit at the end of TRY, roll back in CATCH.

sql
BEGIN TRY
    BEGIN TRANSACTION;
        INSERT INTO Orders (id, total) VALUES (1, 50);
        INSERT INTO Orders (id, total) VALUES (1, 60);  -- PK violation
    COMMIT;
END TRY
BEGIN CATCH
    ROLLBACK;
    THROW;
END CATCH;

Key point: Pairing TRY CATCH with a transaction (commit in TRY, rollback in CATCH) is the pattern interviewers hope to see.

Q34. What is a deadlock and how do you resolve one?

A deadlock happens when two transactions each hold a lock the other needs, so neither can proceed. SQL Server detects this, picks one as the victim, and rolls it back with error 1205 so the other can continue.

You reduce deadlocks by accessing tables in a consistent order across transactions, keeping transactions short, using the right indexes to shrink locking, and retrying the victim in application code.

  • Access objects in the same order across all transactions
  • Keep transactions short and commit quickly
  • Add indexes so locks cover fewer rows
  • Catch error 1205 and retry the transaction

Key point: Consistent lock ordering is the top prevention answer. Retry logic is the runner-up. Both matter.

Q35. What do PIVOT and UNPIVOT do?

PIVOT rotates rows into columns, turning distinct values from one column into headers with aggregated values beneath, which is how you build a cross-tab report. UNPIVOT does the reverse, folding columns back into rows.

PIVOT always aggregates, so you pick an aggregate like SUM. When the value set is dynamic, teams often build the PIVOT with dynamic SQL.

sql
SELECT product, [2025], [2026]
FROM (SELECT product, sales_year, amount FROM Sales) AS src
PIVOT (SUM(amount) FOR sales_year IN ([2025], [2026])) AS pvt;

Q36. How does the CASE expression work?

CASE returns a value based on conditions, like an inline if-else inside a query. The searched form evaluates WHEN conditions in order and returns the first match's THEN value, falling back to ELSE. It works in SELECT, WHERE, ORDER BY, and GROUP BY.

A common use is conditional aggregation: SUM a CASE expression to count rows meeting a condition without a separate query.

sql
SELECT
    SUM(CASE WHEN status = 'shipped' THEN 1 ELSE 0 END) AS shipped,
    SUM(CASE WHEN status = 'pending' THEN 1 ELSE 0 END) AS pending
FROM Orders;

Q37. What is the difference between ISNULL and COALESCE?

ISNULL(a, b) takes exactly two arguments and returns b when a is NULL. COALESCE takes any number of arguments and returns the first non-NULL. COALESCE is standard SQL and more flexible; ISNULL is T-SQL specific.

A subtle difference: ISNULL returns the data type of the first argument, while COALESCE follows data-type precedence rules, which can produce different result types.

sql
SELECT ISNULL(nickname, 'N/A') FROM Users;
SELECT COALESCE(mobile, home, work, 'no phone') FROM Contacts;

Key point: Naming that COALESCE takes many arguments while ISNULL takes two, plus the data-type nuance, marks a careful candidate.

Q38. What is a trigger?

A trigger is code that runs automatically in response to a data event. A DML trigger fires on INSERT, UPDATE, or DELETE, and inside it the inserted and deleted virtual tables hold the affected rows. Triggers enforce rules, audit changes, or cascade updates.

Use them sparingly: hidden logic in triggers is hard to debug, and heavy triggers slow down every write. Many teams prefer explicit application logic or constraints instead.

sql
CREATE TRIGGER trg_AuditSalary
ON Employees
AFTER UPDATE
AS
BEGIN
    INSERT INTO SalaryAudit (employee_id, old_salary, new_salary)
    SELECT d.employee_id, d.salary, i.salary
    FROM deleted d JOIN inserted i ON d.employee_id = i.employee_id
    WHERE d.salary <> i.salary;
END;

Key point: The inserted and deleted virtual tables are the detail interviewers probe. Know that both exist inside a trigger.

Q39. What is the difference between a scalar function and a table-valued function?

A scalar function returns a single value and is called wherever an expression fits. A table-valued function returns a table you can query and join, either inline (a single SELECT) or multi-statement (built up in a table variable).

Inline table-valued functions perform well because the optimizer folds them into the calling query. Scalar functions called per row can hurt performance badly, which is a common tuning finding.

Key point: The per-row cost of scalar functions in a SELECT is a real gotcha. Preferring inline table-valued functions signals tuning experience.

Q40. How would you find duplicate rows in a table?

Group by the columns that define a duplicate, then keep only groups with more than one row using HAVING COUNT(*) > 1. That surfaces which values are duplicated and how many times.

To delete duplicates while keeping one copy, ROW_NUMBER partitioned by those columns is the clean approach: number the copies and delete every row where the number is greater than one.

sql
-- find duplicates
SELECT email, COUNT(*) AS copies
FROM Users
GROUP BY email
HAVING COUNT(*) > 1;

-- delete extras, keep one
WITH ranked AS (
    SELECT *, ROW_NUMBER() OVER (PARTITION BY email ORDER BY id) AS rn
    FROM Users
)
DELETE FROM ranked WHERE rn > 1;

Q41. How do you find the second highest salary?

The clean way is a window function: DENSE_RANK by salary descending, then keep the rows where the rank equals two. DENSE_RANK handles ties correctly so two people tied at the top don't hide the real second place.

An older approach uses TOP with a subquery or OFFSET FETCH, but the window-function version scales to Nth highest by just changing the number.

sql
WITH ranked AS (
    SELECT name, salary,
           DENSE_RANK() OVER (ORDER BY salary DESC) AS rnk
    FROM Employees
)
SELECT name, salary FROM ranked WHERE rnk = 2;

Key point: Reaching for DENSE_RANK and explaining why it handles ties beats the TOP-subquery trick. Both work, one shows depth.

Q42. How do you paginate results in SQL Server?

OFFSET FETCH is the modern way: ORDER BY a stable column, OFFSET past the rows you've seen, then FETCH NEXT the page size. It requires an ORDER BY because paging without a defined order is meaningless.

For deep pages, keyset pagination (a WHERE filter on the last seen key) beats OFFSET, which grows slower the further you page because it still counts through skipped rows.

sql
SELECT name, created_at
FROM Users
ORDER BY created_at DESC, id DESC
OFFSET 40 ROWS FETCH NEXT 20 ROWS ONLY;   -- page 3, size 20

Q43. What is the difference between the CHAR functions LEN and DATALENGTH?

LEN returns the number of characters in a string and ignores trailing spaces. DATALENGTH returns the number of bytes the value uses. For NVARCHAR, DATALENGTH is roughly twice LEN because Unicode uses two bytes per character.

So LEN answers 'how many characters' and DATALENGTH answers 'how much storage', which matters when you're checking whether data fits a column or estimating row size.

sql
SELECT LEN(N'hello  ') AS chars,        -- 5, trailing spaces trimmed
       DATALENGTH(N'hello') AS bytes;    -- 10, NVARCHAR is 2 bytes/char

Watch a deeper explanation

Video: SQL Tutorial - Full Database Course for Beginners (freeCodeCamp.org, YouTube)

Back to question list

MS SQL Server Interview Questions for Experienced Engineers

Experienced17 questions

advanced rounds probe internals, design judgment, and production scars. Expect every answer here to draw a follow-up.

Q44. How do you read a SQL Server execution plan to find a slow query?

Get the actual execution plan, then read right to left and top to bottom, following the thickest arrows because arrow width shows row counts. Look for expensive operators: a clustered index scan where you expected a seek, a key lookup on a hot query, hash or sort spills to tempdb, and a big gap between estimated and actual rows.

That estimate-versus-actual gap is the tell for stale statistics or a bad parameter estimate. The fix is usually a better index, updated statistics, or rewriting the query so the optimizer can use an index.

  • Thick arrows: many rows flowing between operators
  • Scan where you wanted a seek: often a missing or unusable index
  • Key lookup: candidate for a covering index
  • Estimated versus actual row gap: stale stats or a bad estimate

A query-tuning pass

1Capture the actual plan
run with actual execution plan on, using real parameters
2Find the costly operator
thickest arrows, scans, spills, key lookups
3Check estimates vs actuals
a large gap points to stats or parameter sniffing
4Fix and re-measure
add or change an index, update stats, rewrite, then compare plans

The methodology matters more than any single fix. how you reason about the plan is the technical point.

Key point: Walk the plan out loud: read direction, arrow width, the estimate-versus-actual gap. tools support the evidence.

Q45. What is parameter sniffing and when does it cause problems?

On first execution of a stored procedure, SQL Server sniffs the passed parameter values and builds a plan optimized for them, then caches that plan. Usually this helps. It hurts when data is skewed: a plan built for a parameter that matches ten rows gets reused for one that matches a million, or the reverse.

Fixes include OPTION (RECOMPILE) for the statement, OPTIMIZE FOR a representative value, local variables to force an average estimate, or splitting into separate procedures. Each trades plan reuse against getting the right plan per call.

sql
-- recompile so each call gets a plan for its own parameter
SELECT * FROM Orders
WHERE region = @region
OPTION (RECOMPILE);

Key point: Naming both the mechanism (sniff and cache) and at least two fixes (RECOMPILE, OPTIMIZE FOR) is the senior bar.

Q46. How do you choose a good clustered index key?

A good clustered key is narrow, unique, static, and ever-increasing. Narrow because every nonclustered index carries the clustered key as its row pointer. Unique so the engine doesn't add a uniquifier. Static so rows don't move. Ever-increasing (like an identity) so inserts append rather than fragmenting pages.

That's why a monotonic integer identity often beats a wide natural key or a random GUID. A random GUID as the clustered key causes page splits and fragmentation across the whole table.

Key point: Narrow, unique, static, increasing is the checklist. Explaining why nonclustered indexes carry the clustered key shows real internals knowledge.

Q47. What are statistics, and how do they affect query plans?

Statistics are histograms describing the distribution of values in a column, which the optimizer uses to estimate how many rows an operation will touch. Good estimates produce good plans; stale or missing statistics produce bad ones.

SQL Server auto-creates and auto-updates statistics, but on large tables the update threshold can lag, leaving estimates behind reality. UPDATE STATISTICS or a maintenance job keeps them fresh, and the cardinality estimator version can change plan behavior across upgrades.

Key point: statistics maps to the estimate-versus-actual gap from the execution-plan question. They're the same story told from two angles.

Q48. What is the difference between locking and blocking, and how do you diagnose blocking?

Locking is normal: SQL Server takes locks to protect data during reads and writes. Blocking is when one transaction's lock forces another to wait. Short blocking is expected; sustained blocking is a problem, usually from long transactions, missing indexes causing broad locks, or an escalated lock.

Diagnose with the sys.dm_exec_requests and sys.dm_os_waiting_tasks views to see the blocking chain, then shorten transactions, add indexes to narrow locks, or move readers to snapshot isolation so they stop blocking writers.

sql
-- who is blocking whom right now
SELECT blocking_session_id, session_id, wait_type, wait_time, command
FROM sys.dm_exec_requests
WHERE blocking_session_id <> 0;

Q49. What is lock escalation?

When a single statement acquires too many row or page locks (the threshold is around 5,000 locks on one object), SQL Server escalates them to a single table lock to save memory. That one coarse lock is cheaper to track but blocks far more concurrency.

It surfaces as sudden blocking during large updates. Mitigations include batching big modifications into smaller chunks, better indexing so fewer rows are touched, or in specific cases disabling escalation on a table.

Key point: The batching-large-updates fix is what the question needs. Escalation is the symptom, chunked writes are the cure.

Q50. What is an indexed view and when is it worth it?

An indexed view (a materialized view in SQL Server terms) has a unique clustered index built on it, so its results are physically stored and kept in sync automatically as base tables change. It speeds up expensive aggregations and joins that run often.

The cost is write overhead: every change to a base table updates the indexed view too, and there are strict requirements (schema binding, deterministic expressions). Worth it for read-heavy aggregate queries, not for volatile tables.

Key point: The read-speed-versus-write-cost trade-off is the answer. Indexed views pay off only when reads vastly outnumber writes.

Q51. What is table partitioning and what problem does it solve?

Partitioning splits one large table into physical partitions by a key, commonly a date range, while it still looks like a single table to queries. The main wins are manageability and fast data movement: you can switch an entire partition in or out instantly instead of deleting millions of rows.

It also enables partition elimination, where a query touching one date range only scans relevant partitions. Partitioning is a management and maintenance tool more than a pure query-speed feature; people expecting it to fix all slow queries are often disappointed.

Key point: The honest note that partitioning is mainly for manageability, not automatic speed, separates hype from experience.

Q52. How does the transaction log work, and why can it grow uncontrollably?

Every data change is written to the transaction log before the data file, which is what makes durability and rollback possible. The log is a sequential record of changes. In the FULL recovery model, log records stay until a log backup runs, which is how point-in-time restore works.

The log grows out of control when it can't truncate: no log backups in FULL model, a long-running open transaction, or replication or availability groups holding log records. The fix is regular log backups, not shrinking, and finding the transaction or feature pinning the log.

  • FULL recovery model with no log backups is the classic cause
  • A long-running open transaction pins the log
  • sys.databases log_reuse_wait_desc tells you what's blocking truncation
  • Fix with log backups, not repeated shrinks

Key point: Point to log_reuse_wait_desc as the diagnostic. It names exactly why the log can't truncate, which is the whole question.

Q53. What are the recovery models in SQL Server?

SIMPLE reclaims log space automatically and supports no point-in-time restore; you can only restore to the last full or differential backup. FULL logs everything and, with regular log backups, supports point-in-time restore. BULK_LOGGED is a variant of FULL that minimally logs bulk operations to reduce log growth, at the cost of point-in-time restore during those operations.

The choice follows the recovery objective: SIMPLE for data you can rebuild, FULL for anything where losing recent transactions is unacceptable.

ModelPoint-in-time restoreLog growth
SIMPLENoAuto-truncated
FULLYes, with log backupsGrows until backed up
BULK_LOGGEDLimited during bulk opsReduced for bulk ops

Q54. What is index fragmentation and how do you manage it?

Fragmentation is when the logical order of index pages no longer matches their physical order, or pages sit partly empty, which happens as rows are inserted, updated, and deleted. Heavy fragmentation makes range scans read more pages than needed.

Manage it by measuring with sys.dm_db_index_physical_stats, then reorganizing (light, online) below roughly 30 percent and rebuilding (heavier) above it. On modern SSD-backed systems, fragmentation matters less than it once did, so blanket nightly rebuilds are often wasted work.

Key point: The nuance that SSDs make fragmentation less impactful, so measure before rebuilding, indicates current, hands-on knowledge.

Q55. What is a columnstore index and when would you use one?

A columnstore index stores data by column instead of by row, compresses it heavily, and processes it in batches. That makes analytic queries scanning millions of rows and aggregating a few columns dramatically faster than a rowstore index.

Use columnstore for data warehouse and reporting workloads. For transactional workloads with lots of single-row lookups and updates, rowstore stays better, though nonclustered columnstore indexes let one table serve both patterns.

Key point: The OLTP-versus-OLAP framing is the answer. Columnstore wins for analytics scans, rowstore for point lookups and writes.

Q56. How do Always On Availability Groups provide high availability?

An availability group keeps one or more secondary replicas in sync with a primary by shipping transaction log records. If the primary fails, the group fails over to a synchronous secondary, promoting it to primary with no committed data lost. Readable secondaries can also offload reporting.

Synchronous replicas guarantee zero data loss but add commit latency; asynchronous replicas add none but risk losing the last transactions on failover. Choosing per replica is the real design decision.

Key point: The synchronous-versus-asynchronous trade-off (zero data loss versus latency) is what a senior candidate weighs out loud.

Q57. Why can scalar user-defined functions hurt performance, and what changed?

Historically a scalar function in a SELECT ran once per row, row by row, and the optimizer couldn't see inside it, so it produced serial plans and bad estimates. On large result sets this quietly wrecked performance.

SQL Server 2019 added scalar UDF inlining, which folds many scalar functions into the calling query so the optimizer can plan them properly. It's not automatic for every function, so knowing the old cost and the newer inlining feature is the complete answer.

Key point: the 2019 inlining feature by version matters.

Q58. How does optimistic concurrency differ from pessimistic concurrency in SQL Server?

Pessimistic concurrency uses locks: a transaction locks rows it reads or writes so others wait, which prevents conflicts but reduces concurrency. Optimistic concurrency, via SNAPSHOT isolation and row versioning, lets readers see a consistent version without blocking writers, then detects conflicts at commit time.

SNAPSHOT and READ COMMITTED SNAPSHOT trade tempdb space for the version store against much lower blocking. The design question is whether your workload has more read-write contention (favor optimistic) or needs strict serialization (favor pessimistic).

Key point: Tying optimistic concurrency to row versioning in tempdb, and its cost there, is the detail that shows you've run it in production.

Q59. Design question: how would you design an audit trail for a busy transactional database?

Clarify first: what must be captured (which tables, before and after values, who and when), retention, and read patterns. Then pick a mechanism. Temporal tables are the built-in choice: SQL Server keeps a history table automatically with system-versioned validity periods, no triggers to maintain. Triggers give more control but add write overhead and hidden logic. Change Data Capture suits feeding downstream systems.

The closing step is the operational edges: audit writes shouldn't block business transactions, so keep them cheap or asynchronous; partition or archive history so it doesn't bloat; and separate audit permissions so the data can't be quietly altered.

  • Temporal tables: automatic system-versioned history, least maintenance
  • Triggers: full control, but write overhead and harder debugging
  • Change Data Capture: best for streaming changes to other systems
  • Keep audit writes cheap and lock the audit data down

Key point: Structuring the answer clarify, mechanism options, trade-offs, operational edges is what the question is really scoring. Naming temporal tables shows current knowledge.

Q60. How do you approach optimizing a query that suddenly got slow overnight?

Compare what changed. A query that was fine yesterday usually means a plan change, a data volume jump, stale statistics, or a new blocking pattern, not a bug in the SQL. Pull the current plan and compare it to a known-good one from Query Store, which keeps plan history exactly for this.

From there the ladder is familiar: if the plan regressed, force the good plan or fix the statistics; if data grew, revisit indexes; if it's blocking, find the blocker. The discipline is compare-then-fix, not guess-then-change.

Key point: Naming Query Store as the tool for plan regression is the strong move. It answers 'what changed?' with data instead of guesses.

Back to question list

MS SQL Server vs PostgreSQL, MySQL, and Oracle

SQL Server fits teams already on the Microsoft stack: tight integration with .NET, Azure, Windows auth, and first-party tooling like SSMS. It trades open-source freedom and per-core licensing cost for that integration and paid support. PostgreSQL wins on standards compliance and extensibility, MySQL and MariaDB on lightweight web workloads and zero license fees, and Oracle on very large enterprise deployments with deep legacy investment. Knowing these trade-offs out loud is itself an interview signal: it shows you pick a database on merits, not habit.

DatabaseQuery dialectBest atWatch out for
SQL ServerT-SQLMicrosoft and .NET stacks, AzurePer-core licensing cost
PostgreSQLPL/pgSQLStandards, extensions, JSONTuning learning curve
MySQL / MariaDBSQL / stored procsWeb apps, read-heavy workloadsWeaker analytic features
OraclePL/SQLVery large enterprise systemsHigh cost and complexity

How to Prepare for a MS SQL Server Interview

Prepare in layers, and practice out loud. Most SQL Server rounds move from concept questions to live query writing to a design or tuning discussion, so rehearse each stage rather than only reading answers.

  • Master your tier's concepts until you can explain them without notes, then read one tier up for the stretch questions.
  • Type and run every query against a real instance; SQL Server Developer edition is free and behaves like Enterprise.
  • Practice reading an execution plan out loud, because tuning questions score how you reason, not just the final query.
  • Take the quiz on this page to find weak spots, then revisit those questions before the real round.

The typical SQL Server interview flow

1Recruiter or phone screen
background, motivation, a few concept checks
2SQL fundamentals
joins, grouping, subqueries, NULL handling
3Live query writing
write and explain T-SQL under observation
4Design or tuning
indexes, transactions, execution plans, follow-ups

Earlier rounds increasingly run as AI coding interviews. The concepts on this page are what gets probed at every stage.

Test Yourself: MS SQL Server Quiz

Ready to test your MS SQL Server knowledge?

10 questions, about 6 minutes. Score 70% or higher to earn a shareable certificate.

10 questions Instant feedback Free certificate on 70%+

Frequently  Asked  Questions

Which MS SQL Server topics should I prioritize before a technical round?

Prioritize the areas that change real decisions: fundamentals, practical tasks, debugging, trade-offs, and evidence. The highest-value questions are tied to a project example, a validation check, or a failure mode.

Are these questions enough to pass a SQL Server interview?

They cover the question-answer portion well, but most rounds also include live query writing: solving a problem in T-SQL while explaining your thinking. writing queries against a real instance and reading the execution plan is the practice path. Our AI coding interview prep guide covers that format, including how automated evaluation reads your process.

Which SQL Server version do these answers assume?

Modern SQL Server, roughly 2016 and later, which is what almost every team runs. Features like the STRING_SPLIT function, JSON support, and Query Store appear from those versions on. When in doubt in an interview, say which version a feature landed in; it indicates real experience.

Do I need to know T-SQL or is standard SQL enough?

You need T-SQL. Standard SQL covers the SELECT, JOIN, and GROUP BY basics, but SQL Server interviews reach into T-SQL specifics: variables, stored procedures, TRY CATCH error handling, window functions, and functions like ISNULL and TOP. The gap between generic SQL and T-SQL is exactly where intermediate questions live.

How long does it take to prepare for a SQL Server interview?

If you use SQL Server at work, one to two weeks of an hour a day covers this bank with practice runs. Starting colder, plan three to four weeks and write queries daily against the free Developer edition; reading answers without running them is how preparation quietly fails.

Is there a way to test my SQL Server knowledge?

Yes. The quiz on this page scores you as you go and explains every answer, so you find your weak spots fast. Pass the threshold and you can download a shareable certificate with your name and score, free and with no sign-up. It is the quickest way to check yourself before the real round.

From the team that builds coding interviews

Hyring builds the AI Coding Interviewer that runs live technical rounds in 20+ languages for 5,000+ hiring teams. These MS SQL Server questions and scoring notes reflect what actually gets asked and evaluated inside the interviews we host.

See how the AI Coding Interviewer works

Sources

Adithyan RKWritten by Adithyan RK
Surya N
Fact-checked by Surya N
Published on: 1 Apr 2026Last updated: 18 Jun 2026
Share: