|
| 1 | +### YamlMime:ModuleUnit |
| 2 | +uid: learn.wwl.write-advanced-sql-code.knowledge-check |
| 3 | +title: Module assessment |
| 4 | +metadata: |
| 5 | + ai_generated_module_assessment: true |
| 6 | + title: Module assessment |
| 7 | + description: "Knowledge check for writing advanced T-SQL code including CTEs, window functions, JSON, regex, and error handling." |
| 8 | + ms.date: 01/28/2026 |
| 9 | + author: JulianePadrao |
| 10 | + ms.author: jupadrao |
| 11 | + ms.topic: unit |
| 12 | + module_assessment: true |
| 13 | +azureSandbox: false |
| 14 | +labModal: false |
| 15 | +durationInMinutes: 5 |
| 16 | +quiz: |
| 17 | + questions: |
| 18 | + - content: "You need to write a query that calculates a running total of sales ordered by date, while still showing individual order details. Which T-SQL approach should you use?" |
| 19 | + choices: |
| 20 | + - content: "A correlated subquery that sums all orders with a date less than or equal to the current row's date" |
| 21 | + isCorrect: false |
| 22 | + explanation: "Incorrect. While this would work, it's less efficient than using window functions. Correlated subqueries execute for each row, which is computationally expensive for running totals." |
| 23 | + - content: "A recursive CTE that accumulates totals by iterating through each date" |
| 24 | + isCorrect: false |
| 25 | + explanation: "Incorrect. Recursive CTEs are designed for hierarchical data traversal, not running totals. This approach would be unnecessarily complex and potentially slower." |
| 26 | + - content: "An aggregate function with `OVER (ORDER BY)` clause to create a window function" |
| 27 | + isCorrect: true |
| 28 | + explanation: "Correct. Window functions like `SUM(...) OVER (ORDER BY date)` efficiently calculate running totals while preserving row details. The optimizer handles these calculations efficiently." |
| 29 | + - content: "A self-join of the table where all rows with earlier dates are joined and summed" |
| 30 | + isCorrect: false |
| 31 | + explanation: "Incorrect. While this works, it creates a triangular join that becomes extremely slow as data volume increases. Window functions are the standard and efficient solution." |
| 32 | + - content: "You're building a JSON response from relational data and need to include an array of related order items for each customer. Which combination of functions creates nested JSON with arrays from grouped rows?" |
| 33 | + choices: |
| 34 | + - content: "`FOR JSON PATH` with nested subqueries" |
| 35 | + isCorrect: false |
| 36 | + explanation: "Incorrect. While `FOR JSON PATH` can create nested structures, it doesn't directly aggregate rows into arrays within a query. You'd need additional techniques for row aggregation." |
| 37 | + - content: "`JSON_OBJECT` combined with `JSON_ARRAYAGG` to aggregate rows into arrays" |
| 38 | + isCorrect: true |
| 39 | + explanation: "Correct. `JSON_OBJECT` creates JSON objects from key-value pairs, and `JSON_ARRAYAGG` aggregates multiple rows into a JSON array, making them ideal for creating nested JSON from grouped relational data." |
| 40 | + - content: "`OPENJSON` with a `WITH` clause to define the output schema" |
| 41 | + isCorrect: false |
| 42 | + explanation: "Incorrect. `OPENJSON` parses existing JSON into relational rows—it's the opposite direction. To create JSON from relational data, use `JSON_OBJECT` and `JSON_ARRAYAGG`." |
| 43 | + - content: "`JSON_VALUE` and `JSON_QUERY` to extract and combine elements" |
| 44 | + isCorrect: false |
| 45 | + explanation: "Incorrect. These functions extract values from existing JSON strings. They don't construct new JSON from relational data." |
| 46 | + - content: "You need to find customer records where names might be misspelled, such as finding 'John Smith' when the database contains 'Jon Smyth'. Which approach provides the best results for name matching?" |
| 47 | + choices: |
| 48 | + - content: "Use `LIKE` with wildcards such as `WHERE Name LIKE '%ohn%'`" |
| 49 | + isCorrect: false |
| 50 | + explanation: "Incorrect. `LIKE` patterns match literal characters and can't handle character substitutions, transpositions, or missing characters that occur in misspellings." |
| 51 | + - content: "Use `SOUNDEX` to compare phonetic representations" |
| 52 | + isCorrect: false |
| 53 | + explanation: "Incorrect. While SOUNDEX can help with some phonetic variations, it's limited to English phonetics and produces the same code for many different names, leading to false positives." |
| 54 | + - content: "Use `JARO_WINKLER_DISTANCE` which is optimized for name comparison and considers prefix matching" |
| 55 | + isCorrect: true |
| 56 | + explanation: "Correct. Jaro-Winkler is specifically designed for name matching. It gives higher scores to strings matching from the beginning (important for names) and handles common typos well." |
| 57 | + - content: "Use `REGEXP_LIKE` to create a pattern matching all possible misspelling variations" |
| 58 | + isCorrect: false |
| 59 | + explanation: "Incorrect. Creating regex patterns for all possible misspellings is impractical. Fuzzy string matching functions automatically handle character variations without predefined patterns." |
| 60 | + - content: "You're writing a stored procedure that updates multiple tables within a transaction. An error occurs after the first table is updated. What's the correct pattern to ensure data consistency?" |
| 61 | + choices: |
| 62 | + - content: "Use `SET XACT_ABORT ON` only, which automatically rolls back on any error" |
| 63 | + isCorrect: false |
| 64 | + explanation: "Incorrect. While `XACT_ABORT` handles automatic rollback, you should also use `TRY...CATCH` to log errors, perform cleanup, and provide meaningful feedback to callers." |
| 65 | + - content: "Use `TRY...CATCH` with `IF @@TRANCOUNT > 0 ROLLBACK` in the `CATCH` block, then re-raise with `THROW`" |
| 66 | + isCorrect: true |
| 67 | + explanation: "Correct. This pattern ensures cleanup (rollback if needed), allows error logging, and propagates the error to callers. Checking `@@TRANCOUNT` prevents errors when no transaction is active." |
| 68 | + - content: "Check `@@ERROR` after each statement and call `ROLLBACK` if non-zero" |
| 69 | + isCorrect: false |
| 70 | + explanation: "Incorrect. `@@ERROR` resets after each statement, making it easy to miss errors. The `TRY...CATCH` approach provides more reliable, structured error handling." |
| 71 | + - content: "Use multiple nested transactions with `SAVE TRANSACTION` points for each table update" |
| 72 | + isCorrect: false |
| 73 | + explanation: "Incorrect. Save points allow partial rollbacks but don't handle errors automatically. You still need `TRY...CATCH` for proper error management, and the pattern is more complex than necessary." |
| 74 | + - content: "You need to traverse an organizational hierarchy to find all employees who report to a manager at any level, not just direct reports. Which approach best handles variable-depth hierarchical traversal?" |
| 75 | + choices: |
| 76 | + - content: "Multiple self-joins with one join per possible level in the hierarchy" |
| 77 | + isCorrect: false |
| 78 | + explanation: "Incorrect. This requires knowing the maximum depth in advance and becomes unwieldy for deep hierarchies. Each level requires an additional join, making the query complex and inflexible." |
| 79 | + - content: "A recursive CTE that traverses the hierarchy by joining on the manager-employee relationship" |
| 80 | + isCorrect: true |
| 81 | + explanation: "Correct. Recursive CTEs are designed for hierarchical data. The anchor member starts at the root, and the recursive member joins to find the next level, continuing until no more matches are found." |
| 82 | + - content: "A window function with `PARTITION BY` on the manager column" |
| 83 | + isCorrect: false |
| 84 | + explanation: "Incorrect. Window functions operate within partitions but don't traverse relationships. They can't follow manager-employee links across levels like a recursive CTE can." |
| 85 | + - content: "A correlated subquery that finds managers for each employee" |
| 86 | + isCorrect: false |
| 87 | + explanation: "Incorrect. A single correlated subquery can only look one level up or down. Variable-depth traversal requires recursion, which correlated subqueries don't support." |
0 commit comments