1*4520Snw141292 2*4520Snw141292#pragma ident "%Z%%M% %I% %E% SMI" 3*4520Snw141292 4*4520Snw141292# 2001 September 15 5*4520Snw141292# 6*4520Snw141292# The author disclaims copyright to this source code. In place of 7*4520Snw141292# a legal notice, here is a blessing: 8*4520Snw141292# 9*4520Snw141292# May you do good and not evil. 10*4520Snw141292# May you find forgiveness for yourself and forgive others. 11*4520Snw141292# May you share freely, never taking more than you give. 12*4520Snw141292# 13*4520Snw141292#*********************************************************************** 14*4520Snw141292# This file implements regression tests for SQLite library. The 15*4520Snw141292# focus of this file is testing aggregate functions and the 16*4520Snw141292# GROUP BY and HAVING clauses of SELECT statements. 17*4520Snw141292# 18*4520Snw141292# $Id: select3.test,v 1.8 2003/01/31 17:16:37 drh Exp $ 19*4520Snw141292 20*4520Snw141292set testdir [file dirname $argv0] 21*4520Snw141292source $testdir/tester.tcl 22*4520Snw141292 23*4520Snw141292# Build some test data 24*4520Snw141292# 25*4520Snw141292do_test select3-1.0 { 26*4520Snw141292 set fd [open data1.txt w] 27*4520Snw141292 for {set i 1} {$i<32} {incr i} { 28*4520Snw141292 for {set j 0} {pow(2,$j)<$i} {incr j} {} 29*4520Snw141292 puts $fd "$i\t$j" 30*4520Snw141292 } 31*4520Snw141292 close $fd 32*4520Snw141292 execsql { 33*4520Snw141292 CREATE TABLE t1(n int, log int); 34*4520Snw141292 COPY t1 FROM 'data1.txt' 35*4520Snw141292 } 36*4520Snw141292 file delete data1.txt 37*4520Snw141292 execsql {SELECT DISTINCT log FROM t1 ORDER BY log} 38*4520Snw141292} {0 1 2 3 4 5} 39*4520Snw141292 40*4520Snw141292# Basic aggregate functions. 41*4520Snw141292# 42*4520Snw141292do_test select3-1.1 { 43*4520Snw141292 execsql {SELECT count(*) FROM t1} 44*4520Snw141292} {31} 45*4520Snw141292do_test select3-1.2 { 46*4520Snw141292 execsql { 47*4520Snw141292 SELECT min(n),min(log),max(n),max(log),sum(n),sum(log),avg(n),avg(log) 48*4520Snw141292 FROM t1 49*4520Snw141292 } 50*4520Snw141292} {1 0 31 5 496 124 16 4} 51*4520Snw141292do_test select3-1.3 { 52*4520Snw141292 execsql {SELECT max(n)/avg(n), max(log)/avg(log) FROM t1} 53*4520Snw141292} {1.9375 1.25} 54*4520Snw141292 55*4520Snw141292# Try some basic GROUP BY clauses 56*4520Snw141292# 57*4520Snw141292do_test select3-2.1 { 58*4520Snw141292 execsql {SELECT log, count(*) FROM t1 GROUP BY log ORDER BY log} 59*4520Snw141292} {0 1 1 1 2 2 3 4 4 8 5 15} 60*4520Snw141292do_test select3-2.2 { 61*4520Snw141292 execsql {SELECT log, min(n) FROM t1 GROUP BY log ORDER BY log} 62*4520Snw141292} {0 1 1 2 2 3 3 5 4 9 5 17} 63*4520Snw141292do_test select3-2.3 { 64*4520Snw141292 execsql {SELECT log, avg(n) FROM t1 GROUP BY log ORDER BY log} 65*4520Snw141292} {0 1 1 2 2 3.5 3 6.5 4 12.5 5 24} 66*4520Snw141292do_test select3-2.3 { 67*4520Snw141292 execsql {SELECT log, avg(n)+1 FROM t1 GROUP BY log ORDER BY log} 68*4520Snw141292} {0 2 1 3 2 4.5 3 7.5 4 13.5 5 25} 69*4520Snw141292do_test select3-2.4 { 70*4520Snw141292 execsql {SELECT log, avg(n)-min(n) FROM t1 GROUP BY log ORDER BY log} 71*4520Snw141292} {0 0 1 0 2 0.5 3 1.5 4 3.5 5 7} 72*4520Snw141292do_test select3-2.5 { 73*4520Snw141292 execsql {SELECT log*2+1, avg(n)-min(n) FROM t1 GROUP BY log ORDER BY log} 74*4520Snw141292} {1 0 3 0 5 0.5 7 1.5 9 3.5 11 7} 75*4520Snw141292do_test select3-2.6 { 76*4520Snw141292 execsql { 77*4520Snw141292 SELECT log*2+1 as x, count(*) FROM t1 GROUP BY x ORDER BY x 78*4520Snw141292 } 79*4520Snw141292} {1 1 3 1 5 2 7 4 9 8 11 15} 80*4520Snw141292do_test select3-2.7 { 81*4520Snw141292 execsql { 82*4520Snw141292 SELECT log*2+1 AS x, count(*) AS y FROM t1 GROUP BY x ORDER BY y 83*4520Snw141292 } 84*4520Snw141292} {1 1 3 1 5 2 7 4 9 8 11 15} 85*4520Snw141292do_test select3-2.8 { 86*4520Snw141292 execsql { 87*4520Snw141292 SELECT log*2+1 AS x, count(*) AS y FROM t1 GROUP BY x ORDER BY 10-(x+y) 88*4520Snw141292 } 89*4520Snw141292} {11 15 9 8 7 4 5 2 3 1 1 1} 90*4520Snw141292do_test select3-2.9 { 91*4520Snw141292 catchsql { 92*4520Snw141292 SELECT log, count(*) FROM t1 GROUP BY 'x' ORDER BY log; 93*4520Snw141292 } 94*4520Snw141292} {1 {GROUP BY terms must not be non-integer constants}} 95*4520Snw141292do_test select3-2.10 { 96*4520Snw141292 catchsql { 97*4520Snw141292 SELECT log, count(*) FROM t1 GROUP BY 0 ORDER BY log; 98*4520Snw141292 } 99*4520Snw141292} {1 {GROUP BY column number 0 out of range - should be between 1 and 2}} 100*4520Snw141292do_test select3-2.11 { 101*4520Snw141292 catchsql { 102*4520Snw141292 SELECT log, count(*) FROM t1 GROUP BY 3 ORDER BY log; 103*4520Snw141292 } 104*4520Snw141292} {1 {GROUP BY column number 3 out of range - should be between 1 and 2}} 105*4520Snw141292do_test select3-2.12 { 106*4520Snw141292 catchsql { 107*4520Snw141292 SELECT log, count(*) FROM t1 GROUP BY 1 ORDER BY log; 108*4520Snw141292 } 109*4520Snw141292} {0 {0 1 1 1 2 2 3 4 4 8 5 15}} 110*4520Snw141292#do_test select3-2.13 { 111*4520Snw141292# catchsql { 112*4520Snw141292# SELECT log, count(*) FROM t1 GROUP BY 2 ORDER BY log; 113*4520Snw141292# } 114*4520Snw141292#} {0 {0 1 1 1 2 2 3 4 4 8 5 15}} 115*4520Snw141292#do_test select3-2.14 { 116*4520Snw141292# catchsql { 117*4520Snw141292# SELECT log, count(*) FROM t1 GROUP BY count(*) ORDER BY log; 118*4520Snw141292# } 119*4520Snw141292#} {0 {0 1 1 1 2 2 3 4 4 8 5 15}} 120*4520Snw141292 121*4520Snw141292# Cannot have a HAVING without a GROUP BY 122*4520Snw141292# 123*4520Snw141292do_test select3-3.1 { 124*4520Snw141292 set v [catch {execsql {SELECT log, count(*) FROM t1 HAVING log>=4}} msg] 125*4520Snw141292 lappend v $msg 126*4520Snw141292} {1 {a GROUP BY clause is required before HAVING}} 127*4520Snw141292 128*4520Snw141292# Toss in some HAVING clauses 129*4520Snw141292# 130*4520Snw141292do_test select3-4.1 { 131*4520Snw141292 execsql {SELECT log, count(*) FROM t1 GROUP BY log HAVING log>=4 ORDER BY log} 132*4520Snw141292} {4 8 5 15} 133*4520Snw141292do_test select3-4.2 { 134*4520Snw141292 execsql { 135*4520Snw141292 SELECT log, count(*) FROM t1 136*4520Snw141292 GROUP BY log 137*4520Snw141292 HAVING count(*)>=4 138*4520Snw141292 ORDER BY log 139*4520Snw141292 } 140*4520Snw141292} {3 4 4 8 5 15} 141*4520Snw141292do_test select3-4.3 { 142*4520Snw141292 execsql { 143*4520Snw141292 SELECT log, count(*) FROM t1 144*4520Snw141292 GROUP BY log 145*4520Snw141292 HAVING count(*)>=4 146*4520Snw141292 ORDER BY max(n) 147*4520Snw141292 } 148*4520Snw141292} {3 4 4 8 5 15} 149*4520Snw141292do_test select3-4.4 { 150*4520Snw141292 execsql { 151*4520Snw141292 SELECT log AS x, count(*) AS y FROM t1 152*4520Snw141292 GROUP BY x 153*4520Snw141292 HAVING y>=4 154*4520Snw141292 ORDER BY max(n) 155*4520Snw141292 } 156*4520Snw141292} {3 4 4 8 5 15} 157*4520Snw141292do_test select3-4.5 { 158*4520Snw141292 execsql { 159*4520Snw141292 SELECT log AS x FROM t1 160*4520Snw141292 GROUP BY x 161*4520Snw141292 HAVING count(*)>=4 162*4520Snw141292 ORDER BY max(n) 163*4520Snw141292 } 164*4520Snw141292} {3 4 5} 165*4520Snw141292 166*4520Snw141292do_test select3-5.1 { 167*4520Snw141292 execsql { 168*4520Snw141292 SELECT log, count(*), avg(n), max(n+log*2) FROM t1 169*4520Snw141292 GROUP BY log 170*4520Snw141292 ORDER BY max(n+log*2), avg(n) 171*4520Snw141292 } 172*4520Snw141292} {0 1 1 1 1 1 2 4 2 2 3.5 8 3 4 6.5 14 4 8 12.5 24 5 15 24 41} 173*4520Snw141292do_test select3-5.2 { 174*4520Snw141292 execsql { 175*4520Snw141292 SELECT log, count(*), avg(n), max(n+log*2) FROM t1 176*4520Snw141292 GROUP BY log 177*4520Snw141292 ORDER BY max(n+log*2), min(log,avg(n)) 178*4520Snw141292 } 179*4520Snw141292} {0 1 1 1 1 1 2 4 2 2 3.5 8 3 4 6.5 14 4 8 12.5 24 5 15 24 41} 180*4520Snw141292 181*4520Snw141292# Test sorting of GROUP BY results in the presence of an index 182*4520Snw141292# on the GROUP BY column. 183*4520Snw141292# 184*4520Snw141292do_test select3-6.1 { 185*4520Snw141292 execsql { 186*4520Snw141292 SELECT log, min(n) FROM t1 GROUP BY log ORDER BY log; 187*4520Snw141292 } 188*4520Snw141292} {0 1 1 2 2 3 3 5 4 9 5 17} 189*4520Snw141292do_test select3-6.2 { 190*4520Snw141292 execsql { 191*4520Snw141292 SELECT log, min(n) FROM t1 GROUP BY log ORDER BY log DESC; 192*4520Snw141292 } 193*4520Snw141292} {5 17 4 9 3 5 2 3 1 2 0 1} 194*4520Snw141292do_test select3-6.3 { 195*4520Snw141292 execsql { 196*4520Snw141292 SELECT log, min(n) FROM t1 GROUP BY log ORDER BY 1; 197*4520Snw141292 } 198*4520Snw141292} {0 1 1 2 2 3 3 5 4 9 5 17} 199*4520Snw141292do_test select3-6.4 { 200*4520Snw141292 execsql { 201*4520Snw141292 SELECT log, min(n) FROM t1 GROUP BY log ORDER BY 1 DESC; 202*4520Snw141292 } 203*4520Snw141292} {5 17 4 9 3 5 2 3 1 2 0 1} 204*4520Snw141292do_test select3-6.5 { 205*4520Snw141292 execsql { 206*4520Snw141292 CREATE INDEX i1 ON t1(log); 207*4520Snw141292 SELECT log, min(n) FROM t1 GROUP BY log ORDER BY log; 208*4520Snw141292 } 209*4520Snw141292} {0 1 1 2 2 3 3 5 4 9 5 17} 210*4520Snw141292do_test select3-6.6 { 211*4520Snw141292 execsql { 212*4520Snw141292 SELECT log, min(n) FROM t1 GROUP BY log ORDER BY log DESC; 213*4520Snw141292 } 214*4520Snw141292} {5 17 4 9 3 5 2 3 1 2 0 1} 215*4520Snw141292do_test select3-6.7 { 216*4520Snw141292 execsql { 217*4520Snw141292 SELECT log, min(n) FROM t1 GROUP BY log ORDER BY 1; 218*4520Snw141292 } 219*4520Snw141292} {0 1 1 2 2 3 3 5 4 9 5 17} 220*4520Snw141292do_test select3-6.8 { 221*4520Snw141292 execsql { 222*4520Snw141292 SELECT log, min(n) FROM t1 GROUP BY log ORDER BY 1 DESC; 223*4520Snw141292 } 224*4520Snw141292} {5 17 4 9 3 5 2 3 1 2 0 1} 225*4520Snw141292 226*4520Snw141292 227*4520Snw141292 228*4520Snw141292finish_test 229