@@ -322,18 +322,68 @@ async function generateSqlQuery(apiKey: string, schemaInfo: string, question: st
322
322
* Verify parent-child relationships using schema constraints
323
323
- For segmentation analysis:
324
324
* Always ensure segments are MECE (Mutually Exclusive, Collectively Exhaustive)
325
- * Include total counts/values for verification:
326
- - Use UNION ALL to add a "Total" segment
327
- - Calculate totals without segmentation criteria
328
- - Place total row last using ORDER BY
329
- - Example structure:
330
- WITH base_metrics AS (...),
331
- segmented AS (...),
332
- totals AS (...)
333
- SELECT ... FROM segmented
325
+ * For combining segments with totals, use this pattern:
326
+ WITH segment_data AS (
327
+ SELECT
328
+ CASE WHEN condition THEN 'Segment A' ELSE 'Segment B' END as segment,
329
+ metrics...
330
+ FROM source_table
331
+ GROUP BY CASE WHEN condition THEN 'Segment A' ELSE 'Segment B' END
332
+ ),
333
+ total_data AS (
334
+ SELECT
335
+ 'Total' as segment,
336
+ metrics...
337
+ FROM source_table
338
+ )
339
+ SELECT * FROM segment_data
340
+ UNION ALL
341
+ SELECT * FROM total_data
342
+ ORDER BY
343
+ CASE
344
+ WHEN segment = 'Total' THEN 2
345
+ ELSE 1
346
+ END,
347
+ segment;
348
+ * For segment comparisons:
349
+ - Calculate all metrics within each CTE
350
+ - Use clear segment names
351
+ - Ensure consistent column types across UNION
352
+ - Place ORDER BY only in the final query
353
+ - Example structure for comparison analysis:
354
+ WITH metrics_by_segment AS (
355
+ SELECT
356
+ CASE
357
+ WHEN condition THEN 'With Condition'
358
+ ELSE 'Without Condition'
359
+ END as segment,
360
+ COUNT(*) as count,
361
+ AVG(CAST(value AS NUMERIC)) as avg_value,
362
+ SUM(CAST(value AS NUMERIC)) as total_value
363
+ FROM source_table
364
+ GROUP BY
365
+ CASE
366
+ WHEN condition THEN 'With Condition'
367
+ ELSE 'Without Condition'
368
+ END
369
+ ),
370
+ total_metrics AS (
371
+ SELECT
372
+ 'Total' as segment,
373
+ COUNT(*) as count,
374
+ AVG(CAST(value AS NUMERIC)) as avg_value,
375
+ SUM(CAST(value AS NUMERIC)) as total_value
376
+ FROM source_table
377
+ )
378
+ SELECT * FROM metrics_by_segment
334
379
UNION ALL
335
- SELECT 'Total' as segment, ... FROM totals
336
- ORDER BY CASE WHEN segment = 'Total' THEN 1 ELSE 0 END
380
+ SELECT * FROM total_metrics
381
+ ORDER BY
382
+ CASE
383
+ WHEN segment = 'Total' THEN 2
384
+ ELSE 1
385
+ END,
386
+ segment;
337
387
* Add validation comments showing segment math
338
388
* Ensure segment values sum up to totals
339
389
- For segment-level correlations:
0 commit comments