ODI Tool and PLSQL Questions
ODI Tool and PLSQL Questions
Questions
Here are various scenario-based questions for your interview covering ODI (Oracle
Data Integrator) and PL/SQL:
Scenario 3: Debugging
"An ODI process calling a PL/SQL package is failing with unclear error messages.
How would you troubleshoot this issue?"
Scenario 4: Scheduling
"You need to schedule a complex workflow that involves ODI jobs calling PL/SQL
packages, with dependencies between steps. How would you design and implement
this?"
Would you like me to provide sample answers or more detailed scenarios for any of
these questions?
Hi Deepseek I have an interview on ODI tool and PLSQL Could you please provide
different scenario based question for the interview with answers
ODI and PL/SQL Scenario-Based
Interview Questions with
Answers
Here are scenario-based questions along with detailed answers to help you
prepare for your interview on Oracle Data Integrator (ODI) and PL/SQL.
Answer:
1. Use CDC (Change Data Capture) if the source database supports it (Oracle
CDC, LogMiner).
2. Alternative Approach (No CDC):
o Create a temporary staging table to hold all source data.
o Compare key columns between the staging table and target table
using a JOIN in an ODI mapping.
o Use a FILTER condition to load only new or modified records.
o Example SQL in ODI:
sql
Copy
Answer:
Copy
Answer:
Answer:
Copy
DECLARE
TYPE t_ids IS TABLE OF STAGING_TABLE.ID%TYPE;
v_ids t_ids;
BEGIN
SELECT ID BULK COLLECT INTO v_ids FROM STAGING_TABLE;
FORALL i IN 1..v_ids.COUNT
UPDATE TARGET_TABLE
SET STATUS = 'PROCESSED'
WHERE ID = v_ids(i);
END;
2. Limit Batch Size:
o Process in chunks (e.g., 10,000 rows at a time).
3. Use MERGE Instead of Cursor Loops:
sql
Copy
Answer:
sql
Copy
BEGIN
-- Main logic
EXCEPTION
WHEN OTHERS THEN
ROLLBACK;
INSERT INTO ERROR_LOG(ERR_MSG, ERR_DATE)
VALUES (SQLERRM, SYSDATE);
COMMIT;
-- Optionally send email alert
END;
2. Log Errors to a Table:
o Track failed records instead of failing the whole job.
3. Retry Mechanism:
o Use AUTONOMOUS_TRANSACTION for logging without affecting
main transaction.
Answer:
sql
Copy
Answer:
BEGIN
pkg_customer_scoring.calculate_score();
END;
Answer:
1. Approach:
o Use ODI’s SCD Knowledge Module (KM) or a custom mapping.
o For Type 2 SCD, maintain:
Surrogate keys (e.g., CUSTOMER_SK)
Effective dates (START_DATE, END_DATE)
Current flag (IS_CURRENT = 'Y'/'N')
o Steps:
Check for changes (compare source and target).
Expire old records (set END_DATE = SYSDATE, IS_CURRENT = 'N').
Insert new versions (new START_DATE, IS_CURRENT = 'Y').
2. Example ODI Flow:
o LKM: Extract source data.
o IKM: Use IKM Oracle Slowly Changing Dimension or custom SQL.
o Post-Process: Log audit details.
Scenario 2: Handling Large File Processing
Question:
"You need to process a 10GB CSV file in ODI. The load is failing due to memory
issues. How would you optimize this?"
Answer:
Answer:
Answer:
1. Use Recursive WITH Clause (Oracle 11g+):
sql
Copy
WITH org_hierarchy AS (
SELECT employee_id, manager_id, 1 AS level
FROM employees
WHERE manager_id IS NULL
UNION ALL
SELECT e.employee_id, e.manager_id, h.level + 1
FROM employees e
JOIN org_hierarchy h ON e.manager_id = h.employee_id
)
SELECT * FROM org_hierarchy;
2. Alternative (PL/SQL Cursor Loop):
sql
Copy
Answer:
sql
Copy
DECLARE
v_sql VARCHAR2(4000);
v_columns VARCHAR2(1000) := '''Sales'', ''Marketing'', ''IT'''; -- Dynamic input
BEGIN
v_sql := 'SELECT * FROM (
SELECT department, salary FROM employees
)
PIVOT (
AVG(salary) FOR department IN (' || v_columns || ')
)';
EXECUTE IMMEDIATE v_sql;
END;
2. Alternative (XML + DBMS_SQL):
o Use DBMS_SQL for highly dynamic queries.
Answer:
sql
Copy
DECLARE
CURSOR c_data IS SELECT * FROM large_table;
TYPE t_data IS TABLE OF c_data%ROWTYPE;
v_data t_data;
BEGIN
OPEN c_data;
LOOP
FETCH c_data BULK COLLECT INTO v_data LIMIT 1000; -- Process in batches
EXIT WHEN v_data.COUNT = 0;
-- Process batch
END LOOP;
CLOSE c_data;
END;
2. Use FORALL for DML:
o Reduces context switching between SQL and PL/SQL engines.
Answer:
Copy
BEGIN
pkg_validation.validate_data();
END;
2. Error Handling:
o Capture PL/SQL exceptions in ODI Scenarios.
o Log errors to an ODI error table.
Answer:
Would you like a mock interview drill or specific topic deep dive? 😊
ODI Scenario based Interview questions and Answers from basic to advanced
Here’s a comprehensive list of ODI scenario-based interview
questions categorized from basic to advanced, along with detailed answers:
Question:
"How would you create an ODI interface to load data from a flat file (CSV) into an
Oracle table?"
Answer:
1. Create a File Model in ODI for the CSV (define delimiter, encoding).
2. Create an Oracle Model for the target table.
3. Design an Interface:
o Source Datastore: Flat file.
o Target Datastore: Oracle table.
4. Use LKM File to SQL (to stage data).
5. Use IKM Oracle Incremental Update (for insertion).
6. Run the Scenario.
Question:
"You need to load only active customers (STATUS = 'ACTIVE') from a source table.
How would you do this in ODI?"
Answer:
Copy
Question:
"You have customer data in SQL Server and order data in Oracle. How would you join
them in ODI before loading into a data warehouse?"
Answer:
Answer:
sql
Copy
Copy
WHERE NOT EXISTS (SELECT 1 FROM TARGET T WHERE T.PK = S.PK AND
T.HASH_VALUE = S.HASH_VALUE)
2. Alternative: Use a control table to track last extracted IDs.
Question:
"Your ODI job processes 1M records, but some fail due to data issues. How would
you log errors without stopping the load?"
Answer:
Question:
"How would you design an ODI flow for SCD Type 2 (track history with start/end
dates)?"
Answer:
Question:
"How would you set up near real-time data integration using ODI?"
Answer:
Question:
"You receive daily files with varying schemas (e.g., new columns added). How would
you handle this in ODI?"
Answer:
Answer:
Question:
"Your ODI job processes PII (e.g., SSNs). How would you secure this data?"
Answer:
1. Data Masking:
o Use Oracle Data Redaction or ODI Variable Substitution.
2. Encryption:
o LKM File Encrypted for file transfers.
3. ODI Credentials:
o Store passwords in Secure Master Repository.
4. Audit Logs:
o Enable ODI Audit Framework to track access.
You:
1. Setup Models:
o Create Oracle (source) and Snowflake (target) models in Topology.
o Define JDBC connections for both.
2. Interface Design:
o Drag Oracle table as source, Snowflake table as target.
o Use LKM SQL to SQL (AWS/Azure/GCP) for staging.
o Select IKM Snowflake Control Append for loading.
3. Execution:
o Generate scenario → Schedule with OdiStartScen.
You:
1. Preventive Approach:
o Use Pre-Integration Check (e.g., WHERE NOT EXISTS (SELECT 1 FROM
TARGET WHERE PK=SOURCE.PK)).
2. Recovery:
o Enable Error Tables in Physical tab → Log bad records to ERR$_TABLE.
o Use ODI Tools to send alerts with OdiOSCommand (email script).
3. Restartability:
o Implement SCD Type 1 for updates to avoid duplicates.
Pro Tip: Mention ODI 12c+ Smart Restart to skip successful steps.
You:
Choice: PL/SQL for complex logic (e.g., address standardization).
Implementation:
Copy
sql
Copy
BEGIN
pkg_cleanse.clean_customer(:IN_DATA);
END;
3. Advantage:
o Reusable logic across interfaces.
o Better error handling (LOG ERRORS INTO err_table).
You:
Diagnosis First:
1. Check Session Logs for slow steps (e.g., full table scans).
2. Common Fixes:
o SQL Tuning: Add /*+ PARALLEL(8) */ hints in LKM.
o Bulk Processing: Replace row-by-row with FORALL in PL/SQL.
o Commit Frequency: Adjust COMMIT_INTERVAL in IKM.
3. Infrastructure:
o Increase JVM heap size (ODI_JAVA_OPTS=-Xmx4G).
1. Early Start:
o Schedule job at 2 AM with buffer time.
2. Fallback:
o If source fails, use staged data from yesterday (flag as "unverified").
3. Monitoring:
o Implement OdiSleep loops to check source availability.
4. Alerting:
o Trigger Slack/Teams alerts via OdiOSCommand if delayed.
Key Phrase:
"Design for resilience, not just success."
Your Response:
1. Immediate Diagnosis:
o Check if the interface uses a key-based comparison (e.g., WHERE NOT
EXISTS). If missing, add:
sql
Copy
sql
Copy
Key Insight: Shows you understand both quick fixes and robust patterns.
Your Playbook:
sql
Copy
sql
Copy
UPDATE TARGET T
SET status = (SELECT custom_logic(S.col1, S.col2)
FROM STAGING S WHERE S.id = T.id);
3. Nuclear Option:
o Rewrite logic as Java UDF for heavy computations.
1. Session Logs:
o Check step-by-step execution in Operator Navigator → Verify if
LKM/IKM ran.
2. Data Tracing:
o Insert audit rows into a log table during flow:
sql
Copy
Script Example:
shell
Copy
# Check ODI logs
grep "ORA-" $ODI_HOME/log/session_12345.log
Your Blueprint:
1. CDC Setup:
o Enable Oracle GoldenGate or LogMiner-based journalizing.
2. ODI Micro-Batches:
o Schedule scenarios every 1-5 mins using:
shell
Copy
1. Data Masking:
o Use Oracle Data Redaction in staging tables:
sql
Copy
1. Impact Analysis:
o Assess changes to mappings, KMs, and schedules.
2. Version Control:
o Use ODI Git integration to branch/merge changes.
3. Communication:
o Document trade-offs (e.g., "Adding SCD2 will increase load time by
30%").
Phrase to Impress:
"I prototype high-risk changes in a sandbox before altering production workflows."
Want to drill deeper into specific scenarios (e.g., debugging CDC issues) or PL/SQL
optimization patterns? Let me know! 🎯
Yes
Here’s a hardcore mock interview drill with 7 challenging real-world scenarios
and expert-level responses to help you crush your ODI/PL/SQL interview:
Your Response:
sql
Copy
Copy
Your Solution:
sql
Copy
PRAGMA AUTONOMOUS_TRANSACTION;
BEGIN
-- Critical section
COMMIT;
END;
2. Row-Level Locking Strategy:
sql
Copy
Diagnostic Plan:
1. Database-Level Checks:
sql
Copy
Copy
Copy
BEGIN
INSERT INTO session_monitor VALUES (USERENV('SESSIONID'), SYSDATE);
COMMIT;
END;
Expert Investigation:
sql
Copy
Copy
Copy
EXEC DBMS_STATS.GATHER_SCHEMA_STATS('SNP');
o Check for fragmented C$ temporary tables
Compliance Overhaul:
sql
Copy
BEGIN
DBMS_RLS.ADD_POLICY(
object_schema => 'HR',
object_name => 'EMPLOYEES',
policy_name => 'GDPR_MASK',
function_schema => 'SEC',
policy_function => 'MASK_SENSITIVE');
END;
2. ODI-Specific Controls:
o Enable extended auditing in topology:
sql
Copy
Copy
Robust Solution:
shell
Copy
# odi_retry.sh
for i in {1..3}; do
OdiStartScen -SCEN_NAME=API_LOAD && break
sleep 60
done
2. Circuit Breaker Pattern:
sql
Copy
Copy
Migration Playbook:
sql
Copy
Copy
-- Change:
EXECUTE IMMEDIATE 'TRUNCATE TABLE ' || table_name;
-- To:
SET @sql = CONCAT('TRUNCATE TABLE ', table_name);
PREPARE stmt FROM @sql; EXECUTE stmt;
3. Connection Management:
o Implement AWS Secrets Manager integration:
python
Copy
# odi_aws_creds.py
import boto3
secret = boto3.client('secretsmanager').get_secret_value(...)
New chat
Your Response:
1. Data Profiling:
sql
Copy
Copy
-- Suspect expression:
TO_NUMBER(SUBSTR(raw_value, 1, 10)) / 100 -- Accidentally dividing twice?
3. Version Control Check:
o Compare current mapping with last known good version in Git:
bash
Copy
Interviewer:
"When running 10 parallel ODI sessions, the database locks up with
deadlocks. Your PL/SQL package uses FOR UPDATE. How do you fix?"
Your Solution:
1. Row-Level Locking:
sql
Copy
CURSOR c_data IS
SELECT * FROM staging
WHERE status = 'NEW'
FOR UPDATE SKIP LOCKED; -- Critical addition
2. Batch Optimization:
sql
Copy
Copy
# In ODI package
OdiStartScen -SCEN_NAME=LOAD_CHUNK_1 -SYNC=0
OdiSleep 30
OdiStartScen -SCEN_NAME=LOAD_CHUNK_2 -SYNC=0
Interviewer:
"Your ODI agent crashes overnight with OutOfMemory errors when
processing large XML files. How do you troubleshoot?"
Diagnostic Plan:
1. Heap Analysis:
bash
Copy
# Add to odi.conf:
ODI_JAVA_OPTS="-Xmx8G -XX:+HeapDumpOnOutOfMemoryError"
2. File Streaming:
o Replace DOM parsing with SAX in LKM:
xml
Copy
3. JDBC Tuning:
sql
Copy
-- In LKM properties:
fetchSize=1000
Interviewer:
"A simple SELECT query runs fast in SQL Developer but takes hours in
ODI. Why?"
Expert Investigation:
1. Session Tracing:
sql
Copy
Copy
# odi.conf
oracle.jdbc.defaultNChar=true
3. Network Analysis:
bash
Copy
Interviewer:
"Auditors found PII in your ODI error tables. How do you fix this
immediately?"
Emergency Response:
1. Data Redaction:
sql
Copy
Copy
BEGIN
DBMS_SCHEDULER.CREATE_JOB(
job_name => 'PURGE_ERROR_DATA',
job_type => 'PLSQL_BLOCK',
job_action => 'DELETE FROM err$_table WHERE created_date < SYSDATE-7',
repeat_interval => 'FREQ=DAILY');
END;
Interviewer:
"Your CDC-based load missed 3 hours of transactions last night. How do
you recover?"
Disaster Recovery:
1. LogMiner Rescue:
sql
Copy
BEGIN
DBMS_LOGMNR.START_LOGMNR(
starttime => SYSDATE - (4/24),
endtime => SYSDATE - (1/24));
END;
2. ODI Fallback:
o Create emergency interface with:
sql
Copy
Interviewer:
"How would you migrate an Oracle-dependent ODI workflow to
Snowflake?"
Migration Blueprint:
1. KM Adaptation:
o Rewrite IKM using Snowflake syntax:
sql
Copy
Copy
// In Snowflake
CREATE FUNCTION oracle_to_date(str VARCHAR)
RETURNS TIMESTAMP
AS 'return new Date(str);';
Interviewer:
"Your dynamic PL/SQL called from ODI works in dev but fails in prod with
ORA-00942. Why?"
sql
Copy
-- Bad:
EXECUTE IMMEDIATE 'SELECT ' || col_list || ' FROM ' || table_name;
-- Good:
EXECUTE IMMEDIATE 'SELECT COUNT(*) FROM ' ||
DBMS_ASSERT.SQL_OBJECT_NAME(table_name);
2. Schema Verification:
sql
Copy
Deep Dive:
1. Constraint Tracing:
sql
Copy
Interviewer:
"How would you design an ODI architecture for a 24/7 global financial
system?"
Enterprise Blueprint:
1. Topology:
o Regional ODI agents with load balancing
o GoldenGate for CDC with ODI journalizing fallback
2. Resilience:
sql
Copy
-- Heartbeat monitoring
BEGIN
INSERT INTO system_health
VALUES ('ODI_AGENT_EAST', SYSDATE);
COMMIT EVERY 60 SECONDS;
END;
3. Disaster Recovery:
o ODI scenario replication with:
bash
Copy
-- To find non-duplicates
WHERE ROWID IN (
SELECT MIN(ROWID)
FROM SAME_TABLE_ALIAS
GROUP BY KEY_COLUMN1, KEY_COLUMN2
)
2. Use DISTINCT in the source query (simple but less flexible)
sql
Copy
-- In your mapping, add derived columns:
CASE
WHEN ROW_NUMBER() OVER (PARTITION BY KEY_COLUMNS ORDER BY TIMESTAMP_COL
DESC) = 1
THEN 'UNIQUE'
ELSE 'DUPLICATE'
END AS DUP_FLAG
Implementation Options:
Copy
RETURN CASE WHEN v_count > 1 THEN 'Y' ELSE 'N' END;
END;
2. Call from ODI mapping as a derived column
Best Practices:
1. Performance Considerations:
o Add indexes on key columns used for duplicate detection
o Process in batches for large datasets
o Consider hash-based comparison for wide tables
2. Audit Trail:
o Always log duplicate records rather than silently discarding
o Include reason codes for different duplicate types
3. Error Handling:
o Configure ODI error tables to capture duplicate records
o Set up notification for duplicate threshold breaches
Here’s a comprehensive collection of SQL interview
questions categorized from basic to advanced, covering fundamental
concepts, tricky scenarios, and performance optimization:
1. Core Concepts
2. Joins
Q3: Explain INNER JOIN, LEFT JOIN, RIGHT JOIN, and FULL OUTER JOIN with
examples.
A:
sql
Copy
-- INNER JOIN: Only matching rows
SELECT a.id, b.name FROM TableA a INNER JOIN TableB b ON a.id = b.id;
Q4: How do you find records in TableA that don’t exist in TableB?
A:
sql
Copy
SELECT a.* FROM TableA a LEFT JOIN TableB b ON a.id = b.id WHERE b.id IS NULL;
sql
Copy
SELECT MAX(salary) FROM employees WHERE salary < (SELECT MAX(salary) FROM
employees);
-- OR using window functions:
SELECT salary FROM (
SELECT salary, DENSE_RANK() OVER (ORDER BY salary DESC) AS rnk
FROM employees
) WHERE rnk = 2;
-- Optimized:
SELECT e.name FROM employees e JOIN (
SELECT department, AVG(salary) AS avg_sal FROM employees GROUP BY department
) d ON e.department = d.department WHERE e.salary > d.avg_sal;
5. Performance Tuning
Indexes that include all columns needed for a query (avoid table
access).
sql
Copy
CREATE INDEX idx_cover ON employees(department) INCLUDE (salary);
6. Tricky Scenarios
Q11: How do you find duplicate records?
A:
sql
Copy
SELECT email, COUNT(*) FROM users GROUP BY email HAVING COUNT(*) > 1;
sql
Copy
DELETE FROM users
WHERE id NOT IN (
SELECT MIN(id) FROM users GROUP BY email
);
sql
Copy
-- Oracle
SELECT * FROM (
SELECT department, salary FROM employees
) PIVOT (
AVG(salary) FOR department IN ('IT' AS it, 'HR' AS hr)
);
-- SQL Server
SELECT name, [IT], [HR] FROM (
SELECT name, department, salary FROM employees
) AS src PIVOT (
AVG(salary) FOR department IN ([IT], [HR])
) AS pvt;
7. Advanced Joins
sql
Copy
SELECT DISTINCT m.name FROM employees e JOIN employees m ON e.manager_id =
m.id;
sql
Copy
WITH OrgChart AS (
-- Base case: CEO (no manager)
SELECT id, name, manager_id, 1 AS level FROM employees WHERE manager_id IS NULL
UNION ALL
-- Recursive case: Employees with managers
SELECT e.id, e.name, e.manager_id, oc.level + 1
FROM employees e JOIN OrgChart oc ON e.manager_id = oc.id
)
SELECT * FROM OrgChart;
🔹 Real-World Scenarios
sql
Copy
CREATE TABLE employees_backup AS SELECT * FROM employees;
-- Or for large tables:
EXPDP scott/tiger TABLES=employees DIRECTORY=backup_dir
DUMPFILE=employees.dmp;
Here’s a collection of real-world scenario-based SQL questions with
detailed answers, covering common business problems and advanced
techniques:
Scenario:
"An e-commerce platform wants to identify customers who made
purchases above $500 but haven't bought anything in the last 3 months."
Solution:
sql
Copy
WITH big_spenders AS (
SELECT customer_id
FROM orders
WHERE order_amount > 500
),
inactive_customers AS (
SELECT customer_id
FROM orders
GROUP BY customer_id
HAVING MAX(order_date) < CURRENT_DATE - INTERVAL '3 months'
)
SELECT c.customer_name, c.email
FROM customers c
JOIN big_spenders b ON c.customer_id = b.customer_id
JOIN inactive_customers i ON c.customer_id = i.customer_id;
Key Techniques:
2. Employee Hierarchy
Scenario:
"Generate an org chart showing all employees with their managers'
names up to the CEO."
Solution:
sql
Copy
WITH RECURSIVE org_chart AS (
-- Base case: CEO (no manager)
SELECT id, name, manager_id, 1 AS level, CAST(name AS VARCHAR(1000)) AS path
FROM employees WHERE manager_id IS NULL
UNION ALL
-- Recursive case
SELECT e.id, e.name, e.manager_id, oc.level + 1,
oc.path || ' → ' || e.name
FROM employees e
JOIN org_chart oc ON e.manager_id = oc.id
)
SELECT id, name, level, path FROM org_chart
ORDER BY level, name;
Key Techniques:
Recursive CTE
Path building
Hierarchical sorting
Scenario:
"Identify user sessions from web logs where a session expires after 30
minutes of inactivity."
Solution:
sql
Copy
WITH tagged_logs AS (
SELECT
user_id,
event_time,
LAG(event_time) OVER (PARTITION BY user_id ORDER BY event_time) AS prev_time,
CASE WHEN EXTRACT(EPOCH FROM (event_time - LAG(event_time)
OVER (PARTITION BY user_id ORDER BY event_time))) > 1800 OR LAG(event_time)
IS NULL
THEN 1 ELSE 0 END AS new_session
FROM web_logs
),
session_groups AS (
SELECT
user_id,
event_time,
SUM(new_session) OVER (PARTITION BY user_id ORDER BY event_time) AS session_id
FROM tagged_logs
)
SELECT
user_id,
session_id,
MIN(event_time) AS session_start,
MAX(event_time) AS session_end,
COUNT(*) AS events
FROM session_groups
GROUP BY user_id, session_id;
Key Techniques:
4. Inventory Management
Scenario:
"Find products that have been out of stock for more than 7 days but had
sales in the last month."
Solution:
sql
Copy
SELECT p.product_id, p.product_name
FROM products p
JOIN inventory i ON p.product_id = i.product_id
WHERE i.stock_count = 0
AND i.status_date < CURRENT_DATE - INTERVAL '7 days'
AND EXISTS (
SELECT 1 FROM order_items oi
JOIN orders o ON oi.order_id = o.order_id
WHERE oi.product_id = p.product_id
AND o.order_date >= CURRENT_DATE - INTERVAL '1 month'
);
Key Techniques:
Scenario:
"Flag transactions where the same credit card was used in different cities
within 1 hour."
Solution:
sql
Copy
SELECT DISTINCT a.transaction_id, a.card_number, a.city AS city1, b.city AS city2
FROM transactions a
JOIN transactions b ON a.card_number = b.card_number
AND a.transaction_id != b.transaction_id
AND ABS(EXTRACT(EPOCH FROM (a.transaction_time - b.transaction_time)))
<= 3600
WHERE a.city != b.city;
Key Techniques:
Self-join
Time difference calculation
Distance-based fraud pattern
Scenario:
"Calculate the no-show rate for doctors, but only include patients who had
at least 2 previous appointments."
Solution:
sql
Copy
WITH patient_history AS (
SELECT
patient_id,
COUNT(*) FILTER (WHERE status = 'completed') AS completed_visits,
COUNT(*) FILTER (WHERE status = 'no-show') AS no_shows
FROM appointments
GROUP BY patient_id
HAVING COUNT(*) >= 2
)
SELECT
d.doctor_name,
SUM(ph.no_shows) * 100.0 / NULLIF(SUM(ph.completed_visits + ph.no_shows), 0) AS
no_show_rate
FROM patient_history ph
JOIN appointments a ON ph.patient_id = a.patient_id
JOIN doctors d ON a.doctor_id = d.doctor_id
GROUP BY d.doctor_id, d.doctor_name;
Key Techniques:
Scenario:
"Compare conversion rates between two website versions, ensuring
statistical significance (p < 0.05)."
Solution:
sql
Copy
WITH test_results AS (
SELECT
version,
COUNT(*) AS visitors,
COUNT(*) FILTER (WHERE converted = 1) AS conversions
FROM ab_test
GROUP BY version
),
stats AS (
SELECT
SUM(CASE WHEN version = 'A' THEN conversions ELSE 0 END) AS a_conv,
SUM(CASE WHEN version = 'A' THEN visitors ELSE 0 END) AS a_total,
SUM(CASE WHEN version = 'B' THEN conversions ELSE 0 END) AS b_conv,
SUM(CASE WHEN version = 'B' THEN visitors ELSE 0 END) AS b_total
FROM test_results
)
SELECT
a_conv * 100.0 / a_total AS conv_rate_a,
b_conv * 100.0 / b_total AS conv_rate_b,
-- Z-score calculation for statistical significance
(b_conv/b_total - a_conv/a_total) /
SQRT((a_conv + b_conv)/(a_total + b_total) * (1 - (a_conv + b_conv)/(a_total +
b_total)) * (1/a_total + 1/b_total)) AS z_score
FROM stats;
Key Techniques:
Conditional aggregation
Statistical calculations in SQL
Cross-version comparison
Scenario based SQL questions with answers
Here’s a collection of real-world scenario-based SQL questions with detailed
answers, covering common business problems and advanced techniques:
Solution:
sql
Copy
WITH big_spenders AS (
SELECT customer_id
FROM orders
WHERE order_amount > 500
),
inactive_customers AS (
SELECT customer_id
FROM orders
GROUP BY customer_id
HAVING MAX(order_date) < CURRENT_DATE - INTERVAL '3 months'
)
SELECT c.customer_name, c.email
FROM customers c
JOIN big_spenders b ON c.customer_id = b.customer_id
JOIN inactive_customers i ON c.customer_id = i.customer_id;
Key Techniques:
2. Employee Hierarchy
Scenario:
"Generate an org chart showing all employees with their managers' names up to the
CEO."
Solution:
sql
Copy
WITH RECURSIVE org_chart AS (
-- Base case: CEO (no manager)
SELECT id, name, manager_id, 1 AS level, CAST(name AS VARCHAR(1000)) AS path
FROM employees WHERE manager_id IS NULL
UNION ALL
-- Recursive case
SELECT e.id, e.name, e.manager_id, oc.level + 1,
oc.path || ' → ' || e.name
FROM employees e
JOIN org_chart oc ON e.manager_id = oc.id
)
SELECT id, name, level, path FROM org_chart
ORDER BY level, name;
Key Techniques:
Recursive CTE
Path building
Hierarchical sorting
sql
Copy
WITH tagged_logs AS (
SELECT
user_id,
event_time,
LAG(event_time) OVER (PARTITION BY user_id ORDER BY event_time) AS prev_time,
CASE WHEN EXTRACT(EPOCH FROM (event_time - LAG(event_time)
OVER (PARTITION BY user_id ORDER BY event_time))) > 1800 OR LAG(event_time)
IS NULL
THEN 1 ELSE 0 END AS new_session
FROM web_logs
),
session_groups AS (
SELECT
user_id,
event_time,
SUM(new_session) OVER (PARTITION BY user_id ORDER BY event_time) AS session_id
FROM tagged_logs
)
SELECT
user_id,
session_id,
MIN(event_time) AS session_start,
MAX(event_time) AS session_end,
COUNT(*) AS events
FROM session_groups
GROUP BY user_id, session_id;
Key Techniques:
4. Inventory Management
Scenario:
"Find products that have been out of stock for more than 7 days but had sales in the
last month."
Solution:
sql
Copy
SELECT p.product_id, p.product_name
FROM products p
JOIN inventory i ON p.product_id = i.product_id
WHERE i.stock_count = 0
AND i.status_date < CURRENT_DATE - INTERVAL '7 days'
AND EXISTS (
SELECT 1 FROM order_items oi
JOIN orders o ON oi.order_id = o.order_id
WHERE oi.product_id = p.product_id
AND o.order_date >= CURRENT_DATE - INTERVAL '1 month'
);
Key Techniques:
Solution:
sql
Copy
SELECT DISTINCT a.transaction_id, a.card_number, a.city AS city1, b.city AS city2
FROM transactions a
JOIN transactions b ON a.card_number = b.card_number
AND a.transaction_id != b.transaction_id
AND ABS(EXTRACT(EPOCH FROM (a.transaction_time - b.transaction_time)))
<= 3600
WHERE a.city != b.city;
Key Techniques:
Self-join
Time difference calculation
Distance-based fraud pattern
Solution:
sql
Copy
WITH patient_history AS (
SELECT
patient_id,
COUNT(*) FILTER (WHERE status = 'completed') AS completed_visits,
COUNT(*) FILTER (WHERE status = 'no-show') AS no_shows
FROM appointments
GROUP BY patient_id
HAVING COUNT(*) >= 2
)
SELECT
d.doctor_name,
SUM(ph.no_shows) * 100.0 / NULLIF(SUM(ph.completed_visits + ph.no_shows), 0) AS
no_show_rate
FROM patient_history ph
JOIN appointments a ON ph.patient_id = a.patient_id
JOIN doctors d ON a.doctor_id = d.doctor_id
GROUP BY d.doctor_id, d.doctor_name;
Key Techniques:
Solution:
sql
Copy
WITH test_results AS (
SELECT
version,
COUNT(*) AS visitors,
COUNT(*) FILTER (WHERE converted = 1) AS conversions
FROM ab_test
GROUP BY version
),
stats AS (
SELECT
SUM(CASE WHEN version = 'A' THEN conversions ELSE 0 END) AS a_conv,
SUM(CASE WHEN version = 'A' THEN visitors ELSE 0 END) AS a_total,
SUM(CASE WHEN version = 'B' THEN conversions ELSE 0 END) AS b_conv,
SUM(CASE WHEN version = 'B' THEN visitors ELSE 0 END) AS b_total
FROM test_results
)
SELECT
a_conv * 100.0 / a_total AS conv_rate_a,
b_conv * 100.0 / b_total AS conv_rate_b,
-- Z-score calculation for statistical significance
(b_conv/b_total - a_conv/a_total) /
SQRT((a_conv + b_conv)/(a_total + b_total) * (1 - (a_conv + b_conv)/(a_total +
b_total)) * (1/a_total + 1/b_total)) AS z_score
FROM stats;
Key Techniques:
Conditional aggregation
Statistical calculations in SQL
Cross-version comparison
Oracle SQL and PLSQL theoritical and scenario based Interview Questions with
answers
Here's a comprehensive collection of Oracle SQL and PL/SQL interview
questions covering both theoretical concepts and real-world scenarios, with
detailed answers:
Answer:
SGA (System Global Area): Shared memory area with buffer cache, shared
pool, redo log buffer
PGA (Program Global Area): Private memory for each server process
Background Processes: SMON (system monitor), PMON (process monitor),
DBWn (database writer), LGWR (log writer)
Database Files: Datafiles, control files, redo log files
Answer:
sql
Copy
SELECT
salary,
RANK() OVER (ORDER BY salary DESC) AS rank, -- 1,2,2,4
DENSE_RANK() OVER (ORDER BY salary DESC) AS drank, -- 1,2,2,3
ROW_NUMBER() OVER (ORDER BY salary DESC) AS rnum -- 1,2,3,4
FROM employees;
Answer:
sql
Copy
BEGIN
-- Code
EXCEPTION
WHEN NO_DATA_FOUND THEN
DBMS_OUTPUT.PUT_LINE('Record not found');
WHEN OTHERS THEN
DBMS_OUTPUT.PUT_LINE('Error: ' || SQLERRM);
ROLLBACK;
END;
Q4. What are the differences between procedures, functions, and
packages?
Answer:
Procedur
Feature Function Package
e
Return value No Yes N/A
Call context Executable Expression Both
Statefulness Stateless Stateless Persistent
Solution:
sql
Copy
SELECT e.employee_id, e.salary, e.department_id, d.avg_sal
FROM employees e
JOIN (
SELECT department_id, AVG(salary) avg_sal
FROM employees
GROUP BY department_id
) d ON e.department_id = d.department_id
WHERE e.salary > d.avg_sal;
Solution:
sql
Copy
WITH all_numbers AS (
SELECT MIN(invoice_no) min_no, MAX(invoice_no) max_no
FROM invoices
),
expected AS (
SELECT LEVEL + min_no - 1 AS expected_no
FROM all_numbers
CONNECT BY LEVEL <= max_no - min_no + 1
)
SELECT e.expected_no
FROM expected e
LEFT JOIN invoices i ON e.expected_no = i.invoice_no
WHERE i.invoice_no IS NULL;
sql
Copy
CREATE OR REPLACE PROCEDURE archive_orders(p_cutoff_date DATE) IS
BEGIN
INSERT INTO orders_archive
SELECT * FROM orders
WHERE order_date < p_cutoff_date;
COMMIT;
DBMS_OUTPUT.PUT_LINE(SQL%ROWCOUNT || ' orders archived');
EXCEPTION
WHEN OTHERS THEN
ROLLBACK;
RAISE;
END;
Solution:
sql
Copy
CREATE OR REPLACE FUNCTION calculate_tax(
p_amount NUMBER,
p_tax_rate NUMBER
) RETURN NUMBER IS
v_tax NUMBER;
BEGIN
IF p_amount IS NULL OR p_tax_rate IS NULL THEN
RAISE_APPLICATION_ERROR(-20001, 'Input parameters cannot be null');
END IF;
Answer:
Approach:
6. Real-World Scenarios
Solution:
sql
Copy
CREATE OR REPLACE TRIGGER audit_employee_changes
AFTER INSERT OR UPDATE OR DELETE ON employees
FOR EACH ROW
DECLARE
v_action VARCHAR2(10);
BEGIN
IF INSERTING THEN v_action := 'INSERT';
ELSIF UPDATING THEN v_action := 'UPDATE';
ELSE v_action := 'DELETE'; END IF;
Solution:
sql
Copy
CREATE OR REPLACE PROCEDURE process_order_with_retry(
p_order_id NUMBER,
p_max_retries NUMBER := 3
) IS
v_retry_count NUMBER := 0;
v_success BOOLEAN := FALSE;
BEGIN
WHILE v_retry_count < p_max_retries AND NOT v_success LOOP
BEGIN
-- Transaction logic here
INSERT INTO order_processing_log VALUES (...);
COMMIT;
v_success := TRUE;
EXCEPTION
WHEN OTHERS THEN
v_retry_count := v_retry_count + 1;
DBMS_OUTPUT.PUT_LINE('Attempt ' || v_retry_count || ' failed: ' || SQLERRM);
ROLLBACK;
IF v_retry_count < p_max_retries THEN
DBMS_LOCK.SLEEP(5 * v_retry_count); -- Exponential backoff
END IF;
END;
END LOOP;