cswork / libraryOpen practice workspace

Coding questions · Amazon

Explain MySQL to MS SQL Server query syntax differences.

This question evaluates a candidate's understanding of SQL dialect differences between MySQL and MS SQL Server — including alias scope, CTE structure, ordering semantics, and lexical range comparisons that affect query portability and correctness.

transactions

iduser_idamounttxn_date
1100125.002023-07-01
2100240.002023-07-02
3100115.002023-07-03
4100360.002023-07-03
5100130.002023-07-04
Scenario

You are migrating analytics queries from MySQL to MS SQL Server and need to verify candidates understand subtle syntax differences, CTE structure, aliases, ordering and equivalence of filtering clauses.

Question

In MySQL the query

SELECT id, COUNT(*) AS transactions

FROM transactions

GROUP BY id

HAVING transactions > 10;

runs, but the same fails in MS SQL Server. Explain why and rewrite a version portable to both engines.

What does the statement "SELECT * FROM A B;" do and why can it be legal SQL?

Given ORDER BY id, ORDER BY id ASC and ORDER BY id DESC, which one produces a different ordering and why?

Provide the correct multi-CTE skeleton that defines two CTEs, A and B, then queries them.

Will the following three predicates return identical rows for a char column containing only upper-case letters? Justify.

a) col IN ('A','B','C')

b) col BETWEEN 'A' AND 'C'

c) col >= 'A' AND col <= 'C'

Hints

Focus on alias scope rules, default sort order, comma vs alias syntax, WITH clause commas, and lexical range comparisons.

MySQL vs SQL Server Syntax Differences and Multi-CTE Usage

You are migrating analytics queries from MySQL to Microsoft SQL Server and need to verify understanding of cross‑engine SQL syntax details.

Using the transactions table below:

  1. In MySQL, the query

    SELECT id, COUNT(*) AS transactions
    FROM transactions
    GROUP BY id
    HAVING transactions > 10;
    

    runs, but it fails in SQL Server. Explain why, and rewrite a version that is portable to both MySQL and SQL Server.

  2. Explain what the statement SELECT * FROM A B; does and why it can be legal SQL. Clarify how it differs from SELECT * FROM A, B;.

  3. Given ORDER BY id, ORDER BY id ASC, and ORDER BY id DESC, which one produces a different ordering and why? State the default sort direction.

  4. Provide the correct multi‑CTE skeleton that defines two CTEs, A and B, then queries them in a final SELECT (you may use the transactions table to illustrate).

  5. For a CHAR(1) column containing only upper‑case letters, will the following predicates return identical rows? Justify your answer. a) col IN ('A','B','C') b) col BETWEEN 'A' AND 'C' c) col >= 'A' AND col <= 'C'

Write a single SQL script that includes: (i) the portable version of the aggregation query from part (1), and (ii) a concrete multi‑CTE example that computes, per user_id, both the number of transactions and the total transaction amount using two CTEs A and B.

Table transactions

columntypeconstraints
idINTEGERPRIMARY KEY, NOT NULL
user_idINTEGERNOT NULL
amountDECIMAL(10,2)NOT NULL
txn_dateDATENOT NULL

Sample data:

amountidtxn_dateuser_id
2512023-07-011001
4022023-07-021002
1532023-07-031001
6042023-07-031003
3052023-07-041001

Expected output

Conceptually, the candidate should explain and demonstrate:

  1. MySQL allows referring to a SELECT-list alias (transactions) in HAVING, but SQL Server does not; T-SQL requires the aggregate expression itself (e.g., HAVING COUNT() > 10), or a wrapping subquery. A portable query repeats COUNT() in HAVING instead of using the alias.
  2. SELECT * FROM A B; selects from table A and gives it the table alias B (equivalent to SELECT * FROM A AS B). It is not a join; a comma would be required to introduce another table (SELECT * FROM A, B; is a cross join of A and B).
  3. ORDER BY id and ORDER BY id ASC are identical because ASC is the default sort direction. ORDER BY id DESC is the one that produces the opposite ordering (descending). Null placement may vary by engine/settings, but ASC is the default in both MySQL and SQL Server.
  4. Multiple CTEs share a single WITH keyword and are separated by commas, for example: WITH A AS (...), B AS (...) SELECT ... FROM A JOIN B ...; In SQL Server, the previous statement must be properly terminated (typically with a semicolon) before WITH.
  5. For a CHAR(1) column with only uppercase letters, col IN ('A','B','C'), col BETWEEN 'A' AND 'C', and col >= 'A' AND col <= 'C' all return the same rows because BETWEEN is inclusive and comparisons are lexical; the only values in the domain between 'A' and 'C' (inclusive) are 'A', 'B', and 'C'. For multi-character strings or a broader domain, BETWEEN/range predicates can include other values (e.g., 'AA', 'BA', 'CA'), so they would not be equivalent to IN.

For the concrete multi-CTE example, the final SELECT should return one row per user_id with the count of transactions and the total amount, as shown below.

total_amounttxn_countuser_id
7031001
4011002
6011003

Hints

  1. In SQL Server, a HAVING clause cannot reference a SELECT-list alias; repeat the aggregate or wrap the query in an outer SELECT.
  2. SELECT * FROM A B means: select from table A, giving it alias B; spaces introduce aliases, while commas introduce additional tables (joins).
  3. ASC is the default sort direction; only DESC changes the ordering.
  4. Multiple CTEs are defined after a single WITH and are comma-separated; in SQL Server, terminate the prior statement (e.g., with a semicolon) before WITH.
  5. BETWEEN is inclusive and uses lexical comparison; with CHAR(1) uppercase letters, IN ('A','B','C'), BETWEEN 'A' AND 'C', and the equivalent range predicate match the same set, but this may differ for longer strings.