Tableau, Power BI, and Looker Fundamentals Questions
Fundamental concepts and usage patterns for leading business intelligence and data visualization tools Tableau, Power BI, and Looker. Covers connecting to data sources, data modeling for visual dashboards, creating and sharing interactive dashboards and reports, using built-in chart types, calculations and measures, filters and parameters, data governance basics, and best practices for data storytelling and actionable analytics.
MediumTechnical
91 practiced
Write an ANSI SQL query to compute a running monthly revenue total for the last 12 months by month and by customer. Given orders(order_id INT, user_id INT, amount DECIMAL, order_date DATE), output: user_id, year_month, monthly_revenue, running_total. Use window functions and ensure correct partitioning and ordering.
Sample Answer
Approach: aggregate orders by user and month, then compute a running sum per user ordered by month using a window function. To ensure months with no orders are handled, I show a basic version (only months with revenue) and note how to expand to include zero-revenue months by generating a calendar of the last 12 months and LEFT JOINing.SQL (basic version — works in most ANSI-like engines; adjust minor date formatting funcs per dialect):Key points:- Partition by user_id so each customer's running total is independent.- ORDER BY year_month in the window ensures chronological accumulation.- ROWS BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW defines a cumulative sum up to the current month.- Filter uses CURRENT_DATE - INTERVAL '11' MONTH to include the current month plus previous 11 months (12 total).Edge cases & enhancements:- If you need months with zero revenue, create a months calendar CTE for last 12 months, CROSS JOIN distinct users, then LEFT JOIN orders-aggregates to fill zeros.- If your SQL dialect doesn't support TO_CHAR or INTERVAL syntax, replace with equivalent date_trunc/format functions.- For large tables, ensure order_date is indexed and consider pre-aggregating or using materialized views for performance.
sql
WITH monthly AS (
SELECT
user_id,
TO_CHAR(order_date, 'YYYY-MM') AS year_month, -- format month
SUM(amount) AS monthly_revenue
FROM orders
WHERE order_date >= (CURRENT_DATE - INTERVAL '11' MONTH) -- last 12 months inclusive
AND order_date <= CURRENT_DATE
GROUP BY user_id, TO_CHAR(order_date, 'YYYY-MM')
)
SELECT
user_id,
year_month,
monthly_revenue,
SUM(monthly_revenue) OVER (
PARTITION BY user_id
ORDER BY year_month
ROWS BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW
) AS running_total
FROM monthly
ORDER BY user_id, year_month;MediumTechnical
84 practiced
Explain how to implement row-level security (RLS) in Tableau, Power BI, and Looker for a multi-tenant application where users should only see data for their organization. Cover tool-native RLS, database-level RLS, techniques for mapping users to tenants, and how SSO attribute passing can simplify enforcement.
Sample Answer
High-level approach: enforce “users see only their tenant’s rows” either in the BI tool (tool-native RLS) or centrally in the database (DB-level RLS). Ideally combine SSO-driven identity + a mapping table so enforcement is consistent, auditable, and performant.Tool-native RLS- Tableau: - Static: use a join to an entitlement table (user → tenant) in the data source and add a data source filter (calculated: [tenant_id] = lookup from entitlement). - Dynamic: publish a data source with a calculated field that compares tenant_id to USERNAME() or uses ISMEMBEROF() for groups. On Tableau Server, map SAML/SSO attributes to Tableau username or groups so USERNAME() returns an identity you can join on. - Pros: easy to set up per workbook; Cons: must replicate logic across workbooks unless you centralize in published data sources.- Power BI: - Define Roles with DAX filters in Power BI Desktop and publish. For dynamic RLS, use USERPRINCIPALNAME() or USERNAME() inside role filters and join to an entitlement table (e.g., TenantUser[UserPrincipalName] = USERPRINCIPALNAME()). - On Power BI Service, map AAD groups to roles (app workspace access) or rely on Azure AD claims passed via SSO for automatic filtering. - Pros: good integration with Azure AD; Cons: RLS enforced only when using Power BI service; export and direct-query behavior must be considered.- Looker: - Use access_filters in the model: access_filter: { field: user.tenant_id value: “${_user_attributes.tenant_id}” } and set user attribute tenant_id per user (populated via admin UI or SSO). - Alternatively, use Liquid to inject the user attribute into SQL WHERE clauses. - Pros: built-in user_attributes; central models enforce RLS across Looks and Explores.Database-level RLS- Implement once at source (recommended for strongest security): - PostgreSQL example: Set current_tenant for each DB session (e.g., via SET app.current_tenant = '42') as part of connection pooling or connection initialization. - SQL Server has similar WITH (LABEL) or predicate-based features (Row-Level Security using security predicates). - Pros: enforcement independent of BI tool, prevents accidental data leakage via exports or other clients. Cons: requires connection/session handling to inject tenant context; may need support with connection pools.Mapping users to tenants- Entitlement table: canonical mapping table user_id/username → tenant_id, updated from identity provider or HR system.- Groups: map tenant-level AD/Azure groups (e.g., tenant-42-admins) and resolve group membership. Use group claims to scale.- SCIM sync or custom provisioning: keep BI tool user attributes in sync with source-of-truth (IdP).SSO attribute passing to simplify enforcement- Pass tenant_id (or tenant groups) as a claim/attribute in SAML, OIDC or JWT from the IdP.- BI tools can consume claims: - Tableau/Power BI/Looker can map incoming claims to username, groups, or custom user attributes. - With DB-level RLS, inject tenant_id into DB session using the claim at connection time (e.g., the app server or gateway sets SET app.current_tenant).- Benefits: centralizes identity and tenant mapping, eliminates per-tool manual mapping, reduces admin overhead and sync lag.Best practices & trade-offs- Prefer DB-level RLS for strongest, consistent enforcement; use tool-native RLS for additional UX-level restrictions or when DB-level is not feasible.- Use dynamic RLS (username/claims → entitlement join) rather than hardcoding tenant filters.- Ensure connection pools propagate tenant context (use per-tenant DB connections or proxy that sets session variables).- Audit and test: create synthetic accounts to validate cross-tenant isolation; add logging for denied queries.- Performance: index tenant_id; consider materialized views or row-level caching for large tables.Example flow (recommended):1. IdP authenticates user and emits tenant_id claim.2. BI gateway receives claim, sets DB session variable or maps user attribute in the BI tool.3. DB-level RLS policy enforces tenant_id match; BI tool also applies model-level filters for usability.4. Entitlement sync ensures admin console and user attributes stay current.This combination keeps enforcement centralized, simplifies admin work via SSO claims, and gives good UX in Tableau/Power BI/Looker while protecting data at the source.
sql
ALTER TABLE orders ENABLE ROW LEVEL SECURITY;
CREATE POLICY tenant_isolation ON orders
USING (tenant_id = current_setting('app.current_tenant')::int);HardTechnical
79 practiced
A product manager notifies you that conversion rate has declined 12% month over month. Describe your end-to-end investigation plan: quick checks to rule out tracking or ETL bugs, queries to run, dashboards to build (funnel, cohort, traffic source), hypotheses to prioritize, and a communication plan for stakeholders.
Sample Answer
Framework / goals:- Rapidly determine whether the 12% drop is real, isolated, or due to tracking; quantify affected segments; propose mitigations and next steps.Phase 1 — quick-stop checks (10–60 min)- Verify tracking/ETL: compare raw event counts in ingestion vs. reporting tables for the last 3 months.- Check data pipeline jobs status, recent deploys, schema changes, and error logs.- Validate sampling or cohort retention changes (e.g., analytics SDK version rollover).Phase 2 — descriptive queries (1–4 hours)- Overall trend: conversion rate by day/week last 90 days (smooth with 7d MA).- Funnel step counts and conversion rates: visit → sign-up → add-to-cart → purchase, by day.- Traffic-source breakdown: organic, paid, email, referral — CR by source.- Device/OS/browser segmentation: CR by device, app/web, browser versions.- New vs returning users: CR for cohort by acquisition week.- Geography and A/B-test flags: CR by country and experiment variant.Example funnel query outline:Phase 3 — dashboards to build (2–5 days)- Daily funnel dashboard with step counts, conversion rates, 7d MA, and % change.- Cohort retention and conversion by acquisition week.- Traffic-source + campaign performance (CTR, CR, LTV).- Segment explorer: device, OS, browser, geography, promo codes, experiment flags.- Anomaly detector alerts on drops in event volumes or CR.Hypotheses to prioritize (fast → slow)1. Tracking/ETL regression (highest priority) — test by verifying raw vs reported counts.2. Traffic mix shift: lower-quality channels or campaign ended.3. Frontend/backend bug affecting checkout or form submission (errors, JS exceptions).4. A/B test rollout with negative impact.5. Seasonal / pricing / competitor activity.6. Performance/regression: page load times or API latency increased.7. Fraud or spam traffic changes.Validation tests- Replay failed events, check server logs for 4xx/5xx spikes, inspect Sentry/GA error events.- Run lift analysis by traffic source and new vs returning.- Check experiment assignment tables for uneven traffic.Actionable mitigations- If tracking bug: rollback or patch pipeline and backfill missing data.- If traffic mix: pause low-performing campaigns, reallocate budget.- If frontend bug: hotfix and rollback offending commit.- If experiment: pause variant and revert.Communication plan- Immediate (within 1 hour): Send a short alert to PM/CTO/engineering with verification status (tracking OK / suspect), initial numbers (absolute drop), and next steps.- Interim (3–6 hours): Share preliminary findings dashboard, top 3 hypotheses, and recommended mitigation (e.g., pause campaign, rollback).- Follow-up (24–48 hours): Deliver full investigation write-up with dashboards, root cause, actions taken, impact estimate, and plan to prevent recurrence (monitoring, tests).- Stakeholder cadence: daily standup updates until resolved; postmortem within a week with lessons and owners.Metrics to report- Absolute and relative change in conversion, impacted segments, estimated revenue impact, root cause confidence, and action owner + ETA.This plan balances rapid validation with deeper root-cause analysis and clear stakeholder communication so engineering and product can act quickly.
sql
-- compare pageview/event ingestion to reporting table
SELECT day, count(*) as raw_events
FROM raw_events
WHERE event_type='page_view' AND day BETWEEN '2025-10-01' AND '2025-11-30'
GROUP BY day;
SELECT day, count(*) as reported_events
FROM analytics_facts
WHERE event='page_view' AND day BETWEEN '2025-10-01' AND '2025-11-30'
GROUP BY day;sql
WITH steps AS (
SELECT user_id,
MAX(CASE WHEN event='visit' THEN ts END) AS visit_ts,
MAX(CASE WHEN event='signup' THEN ts END) AS signup_ts,
MAX(CASE WHEN event='purchase' THEN ts END) AS purchase_ts
FROM analytics_facts
WHERE day BETWEEN ...
GROUP BY user_id
)
SELECT
count(*) FILTER (WHERE visit_ts IS NOT NULL) as visits,
count(*) FILTER (WHERE signup_ts IS NOT NULL) as signups,
count(*) FILTER (WHERE purchase_ts IS NOT NULL) as purchases
FROM steps;MediumTechnical
66 practiced
You receive a dataset with missing values for product_category and many NULL prices. As a BI analyst building dashboards, describe strategies you would use to handle missing categorical and numeric data in Tableau/Power BI/Looker, including imputation, bucketing, user communication, and filtering. Explain pros and cons of each approach.
Sample Answer
Start by clarifying requirements with stakeholders: how important is accuracy vs. completeness, and will NULL prices or unknown categories be actionable or just noise? Then apply a combination of strategies depending on use-case (exploration, operational dashboards, executive KPIs).Categorical (product_category)- Show "Unknown / Missing" explicitly: create a category labelled "Missing" in Looker/Power BI/Tableau. - Pros: honest, preserves row count, avoids misleading buckets. - Cons: can clutter visuals, may hide patterns if many missing.- Impute from business rules: map SKU → category using lookup tables or join to master data. - Pros: recovers true values when reliable. - Cons: risk of incorrect mappings; requires maintenance.- Predictive imputation: use a model (e.g., decision tree) to infer category from product attributes. - Pros: higher recovery for complex cases. - Cons: needs training data, introduces modeling errors; document confidence.- Bucketing: group rare categories into "Other" and keep missing as its own bucket. - Pros: reduces noise, easier to read charts. - Cons: loses granularity.Numeric (price)- Leave NULL and indicate in visuals: show count of missing, and exclude from aggregate price metrics but surface missing-rate. - Pros: transparent; avoids biasing averages. - Cons: may reduce sample size for metrics.- Impute with domain-aware values: median by category, or use last-known price: - Pros: simple, preserves distribution better than mean. - Cons: incorrect if price varies over time.- Model-based imputation: regression using features (cost, supplier, SKU). - Pros: more accurate when relationships exist. - Cons: complexity, needs validation; propagate uncertainty.- Bucketing prices (ranges) and include "Price Missing" bucket: - Pros: simplifies analysis and includes missing as meaningful segment. - Cons: reduces precision.User communication & dashboard UX- Always surface data quality: header badges, tooltips, KPI footnotes with missing-rate and imputation method.- Provide interactive filters: allow users to include/exclude missing or imputed rows; show toggle for “include imputed prices.”- Confidence indicators: color-code metrics that rely heavily on imputed values.- Drill-through to examples: let analysts inspect rows with missing values to validate imputation rules.Filtering & governance- For operational decisions, prefer conservative filtering (exclude NULL prices until fixed).- For exploratory/strategic dashboards, impute with clear annotation to avoid misleading stakeholders.- Implement ETL fixes upstream where possible: master-data joins, validation rules, and monitoring alerts for missing-value spikes.Trade-offs summary- Transparency vs. completeness: imputation increases completeness but risks bias; explicit "Missing" preserves truth but may limit analysis.- Simplicity vs. accuracy: heuristic imputations are easy but less accurate than models.- Always document method, show missing-rate, and provide UI controls so consumers can choose how to handle missing data.
EasyTechnical
66 practiced
Given a dataset with revenue and cost columns, write the calculated-field formula to compute profit margin in Tableau, the equivalent DAX measure in Power BI, and the LookML measure in Looker. Explain where each calculation is evaluated (data source, semantic layer, or visualization layer) and how evaluation location affects performance.
Sample Answer
Tableau (calculated field)Create a calculated field named Profit Margin:Or as a single expression:Evaluation location: visualization layer (Tableau Desktop/Server computes the calculation after pulling data unless you use a custom SQL or pushdown via a live connection; with live connections, the database may aggregate if you use raw fields—Tableau will often generate SQL that performs SUMs in the data source).Power BI (DAX measure)Create a measure in the model:Evaluation location: semantic/model layer (DAX runs in the Power BI engine (VertiPaq) when using imported data; for DirectQuery, DAX may be translated into queries pushed to the source).Looker (LookML measure)In view file:Evaluation location: semantic layer / query generation (Looker compiles LookML into SQL and pushes the aggregation to the database).How evaluation location affects performance- Visualization-layer (Tableau calculated fields done post-query) can be slower or pull more data if heavy row-level work is done client-side; but Tableau often pushes aggregated SQL to the DB for simple SUMs, so design matters.- Semantic/model-layer (Power BI DAX in-memory) is very fast for imported data due to VertiPaq compression and in-memory execution; DirectQuery reduces performance because queries hit the source.- LookML (Looker) pushes SQL to the data warehouse—best for scalability if the warehouse is optimized; avoids moving large datasets to the BI tool.Best practice: push aggregations/calculations to the data/semantic layer (DB or model) when possible to leverage engine performance and reduce data movement; use visualization-layer calculations only for presentation-specific transforms.
sql
SUM([Revenue]) - SUM([Cost])
/
SUM([Revenue])sql
SUM([Revenue] - [Cost]) / SUM([Revenue])dax
Profit Margin =
DIVIDE(
SUM('Sales'[Revenue]) - SUM('Sales'[Cost]),
SUM('Sales'[Revenue]),
0
)yaml
measure: profit_margin {
type: number
sql: (SUM(${revenue}) - SUM(${cost})) / NULLIF(SUM(${revenue}),0) ;;
value_format_name: "percent_2"
}Unlock Full Question Bank
Get access to hundreds of Tableau, Power BI, and Looker Fundamentals interview questions and detailed answers.
Sign in to ContinueJoin thousands of developers preparing for their dream job.