Skip to content

Phase 5 — Advanced SQL Queries (q21–q40)

This section documents advanced joins, grouping, subqueries, and EXISTS/NOT EXISTS patterns used in the backend.

Basic SQL Queries Backend Logic


Query Catalog

q21 — Join User + FamilyMember

SELECT u.user_id, u.email,
       fm.member_id, CONCAT(fm.first_name,' ',fm.last_name) AS member_name,
       fm.relationship
FROM User u
JOIN FamilyMember fm ON fm.user_id = u.user_id
ORDER BY u.user_id DESC, fm.member_id DESC;

q22 — Users with no family members

SELECT u.user_id, u.email
FROM User u
LEFT JOIN FamilyMember fm ON fm.user_id = u.user_id
WHERE fm.member_id IS NULL;

q23 — Family size per user

SELECT u.user_id, u.email, COUNT(fm.member_id) AS family_count
FROM User u
LEFT JOIN FamilyMember fm ON fm.user_id = u.user_id
GROUP BY u.user_id, u.email
ORDER BY family_count DESC;

q24 — Event report (HealthEvent + FamilyMember + HealthCondition)

SELECT he.event_id,
       CONCAT(fm.first_name,' ',fm.last_name) AS family_member,
       hc.condition_name,
       he.severity,
       he.event_date
FROM HealthEvent he
JOIN FamilyMember fm ON he.member_id = fm.member_id
JOIN HealthCondition hc ON he.condition_id = hc.condition_id
ORDER BY he.event_date DESC
LIMIT 20;

q25 — Events per condition

SELECT hc.condition_name, COUNT(*) AS total_events
FROM HealthEvent he
JOIN HealthCondition hc ON he.condition_id = hc.condition_id
GROUP BY hc.condition_name
ORDER BY total_events DESC;

q26 — Conditions with zero events

SELECT hc.condition_id, hc.condition_name
FROM HealthCondition hc
LEFT JOIN HealthEvent he ON he.condition_id = hc.condition_id
WHERE he.event_id IS NULL;

q27 — Members with more than 1 event

SELECT he.member_id, COUNT(*) AS event_count
FROM HealthEvent he
GROUP BY he.member_id
HAVING COUNT(*) > 1
ORDER BY event_count DESC;

q28 — Latest event per member

SELECT he.*
FROM HealthEvent he
JOIN (
  SELECT member_id, MAX(event_date) AS max_date
  FROM HealthEvent
  GROUP BY member_id
) m ON m.member_id = he.member_id AND m.max_date = he.event_date
ORDER BY he.event_date DESC;

q29 — History + member + condition

SELECT mh.event_id,
       CONCAT(fm.first_name,' ',fm.last_name) AS member_name,
       hc.condition_name,
       mh.diagnosis_date,
       mh.notes
FROM MedicalHistory mh
JOIN FamilyMember fm ON mh.member_id = fm.member_id
JOIN HealthCondition hc ON mh.condition_id = hc.condition_id
ORDER BY mh.diagnosis_date DESC;

q30 — Diagnoses per condition

SELECT hc.condition_name, COUNT(*) AS diagnoses
FROM MedicalHistory mh
JOIN HealthCondition hc ON mh.condition_id = hc.condition_id
GROUP BY hc.condition_name
ORDER BY diagnoses DESC;

q31 — Members with history but no events

SELECT DISTINCT mh.member_id
FROM MedicalHistory mh
WHERE NOT EXISTS (
  SELECT 1 FROM HealthEvent he
  WHERE he.member_id = mh.member_id
);

q32 — Members with events but no history

SELECT DISTINCT he.member_id
FROM HealthEvent he
WHERE NOT EXISTS (
  SELECT 1 FROM MedicalHistory mh
  WHERE mh.member_id = he.member_id
);

q33 — Unresolved alerts per member

SELECT member_id, COUNT(*) AS unresolved
FROM RiskAlert
WHERE status <> 'Resolved'
GROUP BY member_id
HAVING COUNT(*) >= 1
ORDER BY unresolved DESC;

q34 — Alert work queue

SELECT ra.alert_id,
       CONCAT(fm.first_name,' ',fm.last_name) AS member_name,
       ra.risk_level,
       ra.status,
       ra.created_date
FROM RiskAlert ra
JOIN FamilyMember fm ON ra.member_id = fm.member_id
WHERE ra.status <> 'Resolved'
ORDER BY FIELD(ra.risk_level,'High','Medium','Low'), ra.created_date DESC;

q35 — Members with no alerts

SELECT fm.member_id, fm.first_name, fm.last_name
FROM FamilyMember fm
WHERE NOT EXISTS (
  SELECT 1 FROM RiskAlert ra
  WHERE ra.member_id = fm.member_id
);

q36 — Conditions with above-average events

SELECT hc.condition_name, COUNT(*) AS total_events
FROM HealthEvent he
JOIN HealthCondition hc ON hc.condition_id = he.condition_id
GROUP BY hc.condition_name
HAVING COUNT(*) >
  (SELECT AVG(cnt)
   FROM (SELECT COUNT(*) AS cnt FROM HealthEvent GROUP BY condition_id) t)
ORDER BY total_events DESC;

q37 — High severity events with member + condition

SELECT he.event_id,
       CONCAT(fm.first_name,' ',fm.last_name) AS member_name,
       hc.condition_name,
       he.event_date
FROM HealthEvent he
JOIN FamilyMember fm ON fm.member_id = he.member_id
JOIN HealthCondition hc ON hc.condition_id = he.condition_id
WHERE he.severity = 'High'
ORDER BY he.event_date DESC;

q38 — Average onset age per condition

SELECT hc.condition_name, AVG(he.onset_age) AS avg_onset_age
FROM HealthEvent he
JOIN HealthCondition hc ON hc.condition_id = he.condition_id
WHERE he.onset_age IS NOT NULL
GROUP BY hc.condition_name
ORDER BY avg_onset_age DESC;

q39 — Members with at least one HIGH risk alert

SELECT fm.member_id, fm.first_name, fm.last_name
FROM FamilyMember fm
WHERE EXISTS (
  SELECT 1 FROM RiskAlert ra
  WHERE ra.member_id = fm.member_id AND ra.risk_level = 'High'
);

q40 — Members with both events and alerts

SELECT fm.member_id, fm.first_name, fm.last_name
FROM FamilyMember fm
WHERE EXISTS (SELECT 1 FROM HealthEvent he WHERE he.member_id = fm.member_id)
  AND EXISTS (SELECT 1 FROM RiskAlert ra WHERE ra.member_id = fm.member_id);

Notes

  • This catalog mirrors backend query constants exactly (q21q40).
  • Advanced set covers joins, grouping, HAVING, subqueries, and EXISTS logic.