Skip to content
BytePatterns

DEA-C01 · Domain 3: Data Operations and Support · 22% of the exam

Task 3.2: Analyze data by using AWS services

Answering questions from the data: SQL and views in Redshift and Athena, Spark notebooks in Athena, dashboards, cleaning data before analysis, aggregations, rolling averages and pivots, and when a provisioned service beats a serverless one.

Study it

  • Querying S3 with Athena: partitions, formats and workgroups

    Lesson coming

  • SQL for analysis: aggregations, grouping, pivots and views

    Partly covered by: Aggregations & GROUP BY, INNER and OUTER JOINs, CTEs and Recursion

  • Rolling averages and window functions

    Partly covered by: Window Functions

  • Dashboards and notebooks: Amazon Quick Sight and Athena for Apache Spark

    Lesson coming

  • Provisioned or serverless: Redshift, EMR and Athena compared

    Partly covered by: AWS Cost Levers

Sample questions

Try each one before opening the answer. Every option is explained, with the AWS documentation page that proves it.

Question 1 · choose 1

A Redshift table daily_sales has one row per store per day (store_id, sale_date, revenue), with no missing days. Analysts need each store's 7-day rolling average revenue, including the current day, next to every row. Which expression should they use?

  1. AAVG(revenue) OVER (PARTITION BY store_id ORDER BY sale_date ROWS BETWEEN 7 PRECEDING AND CURRENT ROW)
  2. BAVG(revenue) OVER (PARTITION BY store_id ORDER BY sale_date ROWS BETWEEN 6 PRECEDING AND CURRENT ROW)
  3. CAVG(revenue) OVER (PARTITION BY store_id), with no ORDER BY in the window
  4. DAVG(revenue) with GROUP BY store_id, sale_date in the same query
Show the answer and why
  • AAVG(revenue) OVER (PARTITION BY store_id ORDER BY sale_date ROWS BETWEEN 7 PRECEDING AND CURRENT ROW)

    Incorrect

    Seven preceding rows plus the current row is an 8-day window.

  • BAVG(revenue) OVER (PARTITION BY store_id ORDER BY sale_date ROWS BETWEEN 6 PRECEDING AND CURRENT ROW)

    Correct

    The frame covers the current row and the 6 rows before it in date order, which is 7 days for each store, and a window function keeps every row.

  • CAVG(revenue) OVER (PARTITION BY store_id), with no ORDER BY in the window

    Incorrect

    Without ORDER BY the frame is the whole partition, so every row gets the store's all-time average.

  • DAVG(revenue) with GROUP BY store_id, sale_date in the same query

    Incorrect

    Grouping by store and day averages one row per group. It returns each day's own revenue, not a rolling value.

Rolling metrics are window functions with an ordered frame. ROWS BETWEEN n PRECEDING AND CURRENT ROW covers n + 1 rows.

Question 2 · choose 1

A finance team runs a few dozen analytical queries a week at unpredictable times. Between those queries the data warehouse sits idle. The team does not want to size or manage clusters and wants to pay for compute only when queries run. Which option fits best?

  1. AA provisioned Redshift cluster bought with 1-year reserved nodes
  2. BA provisioned Redshift cluster with concurrency scaling turned on
  3. CAmazon Redshift Serverless
  4. DA provisioned Redshift cluster with elastic resize before each query
Show the answer and why
  • AA provisioned Redshift cluster bought with 1-year reserved nodes

    Incorrect

    Reserved nodes discount the hourly rate of nodes that run all the time. The team would pay for an idle cluster most of the week.

  • BA provisioned Redshift cluster with concurrency scaling turned on

    Incorrect

    Concurrency scaling adds capacity for bursts of concurrent queries. The main cluster still has to be sized and paid for while idle.

  • CAmazon Redshift Serverless

    Correct

    Redshift Serverless provisions and scales capacity automatically, and you pay only for the capacity you use.

  • DA provisioned Redshift cluster with elastic resize before each query

    Incorrect

    Resizing is a manual capacity change. Someone still sizes the cluster, and it bills while it waits between queries.

Steady, predictable load favors provisioned capacity with reservations; occasional and unpredictable load favors serverless, where idle time costs no compute.

Question 3 · choose 1

Data scientists want to explore data in Amazon S3 interactively with PySpark in notebooks. They do not want to plan, configure or manage any compute, and they want capacity to scale up and down on its own. Which service should they use?

  1. AAmazon Athena for Apache Spark
  2. BAmazon EMR with JupyterHub
  3. CAmazon Athena SQL queries in the console query editor
  4. DAn AWS Glue DataBrew project on a sample of the data
Show the answer and why
  • AAmazon Athena for Apache Spark

    Correct

    Apache Spark on Athena is serverless: you submit Spark code from notebooks and Athena determines and scales the compute it needs.

  • BAmazon EMR with JupyterHub

    Incorrect

    JupyterHub on EMR gives notebooks, but the team would choose, size and manage the cluster.

  • CAmazon Athena SQL queries in the console query editor

    Incorrect

    The query editor runs SQL. It does not run PySpark code in notebooks.

  • DAn AWS Glue DataBrew project on a sample of the data

    Incorrect

    DataBrew is a visual, no-code preparation tool. It does not run the team's PySpark code.

Athena offers two engines: SQL and Apache Spark. The Spark engine gives notebook users PySpark without any cluster to manage.

Question 4 · choose 1

An Amazon Athena table has an orders column, tags, that holds an array of strings. An analyst needs one output row per tag for each order, to count orders by tag. Which SQL construct should the analyst use?

  1. Aarray_join(tags, ',') in the SELECT list
  2. BCROSS JOIN UNNEST(tags) AS t(tag)
  3. Ccardinality(tags) in the SELECT list
  4. Dtags[1] in the SELECT list
Show the answer and why
  • Aarray_join(tags, ',') in the SELECT list

    Incorrect

    array_join converts the array into a single string, so each order still produces one row.

  • BCROSS JOIN UNNEST(tags) AS t(tag)

    Correct

    CROSS JOIN with UNNEST flattens an array into multiple rows, one for each element.

  • Ccardinality(tags) in the SELECT list

    Incorrect

    cardinality returns the length of the array, not its elements.

  • Dtags[1] in the SELECT list

    Incorrect

    The [] operator returns one element, here the first, so the other tags are lost.

Counting by array element needs the array turned into rows first; UNNEST does that, and GROUP BY can then count per tag.

Question 5 · choose 1

In Amazon Redshift, a report needs one row per order with all product names of the order in a single comma-separated string, sorted alphabetically. Which function should a data engineer use?

  1. ACONCAT(order_id, product_name) in the SELECT list, grouped by order_id
  2. BLISTAGG(product_name, ',') WITHIN GROUP (ORDER BY product_name)
  3. CCOUNT(DISTINCT product_name) with GROUP BY order_id
  4. DMAX(product_name) with GROUP BY order_id
Show the answer and why
  • ACONCAT(order_id, product_name) in the SELECT list, grouped by order_id

    Incorrect

    CONCAT joins two expressions within one row. It does not combine values from several rows of a group.

  • BLISTAGG(product_name, ',') WITHIN GROUP (ORDER BY product_name)

    Correct

    For each group, LISTAGG orders the rows by the ORDER BY expression and concatenates the values into a single string.

  • CCOUNT(DISTINCT product_name) with GROUP BY order_id

    Incorrect

    COUNT returns how many values there are, not the values themselves.

  • DMAX(product_name) with GROUP BY order_id

    Incorrect

    MAX returns a single value from each group, so the other product names are lost.

String aggregation across rows is LISTAGG's job; WITHIN GROUP controls the order of the values in the result.

Question 6 · choose 1

A Redshift query computes revenue / visits for each store. Some stores have 0 visits on some days, and the query fails with a division-by-zero error. The report should show NULL for those days. How should a data engineer write the expression?

  1. Arevenue / NULLIF(visits, 0)
  2. Brevenue / COALESCE(visits, 0)
  3. Crevenue / NVL(visits, 1)
  4. DROUND(revenue / visits, 2)
Show the answer and why
  • Arevenue / NULLIF(visits, 0)

    Correct

    NULLIF returns null when its two arguments are equal, so a zero divisor becomes null and the division returns null instead of failing.

  • Brevenue / COALESCE(visits, 0)

    Incorrect

    COALESCE returns the first non-null value; a visits value of 0 is not null, so the divisor is still 0.

  • Crevenue / NVL(visits, 1)

    Incorrect

    NVL is the same as COALESCE and replaces only nulls, so a 0 divisor stays 0.

  • DROUND(revenue / visits, 2)

    Incorrect

    ROUND rounds the result of the division, which still fails before rounding can happen.

NULLIF is the inverse of COALESCE: it turns a chosen value into null, which makes it the standard guard against dividing by zero.

Question 7 · choose 1

Business-critical dashboards run Amazon Athena queries from one workgroup. At peak times, their queries wait in line behind queries from other teams. The team wants dedicated processing capacity for the dashboard workgroup without changing any SQL. What should a data engineer do?

  1. ATurn on query result reuse with a maximum age for the dashboard workgroup
  2. BSet a per-query data usage limit on the other teams' workgroups
  3. CCreate a capacity reservation and assign the dashboard workgroup to it
  4. DPartition the dashboard tables by date and filter on the partitions
Show the answer and why
  • ATurn on query result reuse with a maximum age for the dashboard workgroup

    Incorrect

    Result reuse returns stored results when a query is run again. New or changed queries still compete for capacity.

  • BSet a per-query data usage limit on the other teams' workgroups

    Incorrect

    Data usage limits cap how much data a query scans. They do not reserve capacity for the dashboards.

  • CCreate a capacity reservation and assign the dashboard workgroup to it

    Correct

    Capacity reservations give dedicated serverless capacity, let you choose which workloads use it, and need no changes to SQL queries.

  • DPartition the dashboard tables by date and filter on the partitions

    Incorrect

    Partitioning reduces the data each query scans, but it requires query changes and reserves no capacity.

When concurrency, not scan size, is the problem, Athena capacity reservations give a workload its own processing capacity.

Question 8 · choose 1

Analysts repeat the same join of three Athena tables in many queries. They want a named object they can query like a table, which always reflects the latest data in the underlying tables and stores no extra copy. What should a data engineer create?

  1. AA CTAS table built from the join
  2. BA saved query that holds the join
  3. CA summary table filled by INSERT INTO each hour
  4. DAn Athena view defined by the join
Show the answer and why
  • AA CTAS table built from the join

    Incorrect

    CTAS stores the query results as data files in S3, a copy that does not change when the source tables do.

  • BA saved query that holds the join

    Incorrect

    Saved queries can be edited and run in the console, but analysts cannot select from them as a table.

  • CA summary table filled by INSERT INTO each hour

    Incorrect

    INSERT INTO adds rows to a stored table, which is an extra copy that is up to an hour old.

  • DAn Athena view defined by the join

    Correct

    A view is a logical table, not a physical one; its query runs each time the view is referenced, so it reflects current data.

Views give reusable logic without storage; CTAS and INSERT INTO give materialized copies when query speed matters more than freshness.

Practise domain 3 →Practise all domains →