Re: [sqlite] Min() ; was: Re: if exist
On 3/9/2010 2:13 PM, P Kishor wrote: <> about the following example I provided: >> select min(c) from T where 1=2 >> group by foo >> >> returns no rows, presumably because the null value was removed from the >> aggregated set. >> Foo was simply my shorthand for "another column, not column 'c' ", Sorry. The slanty lines are just drawing attention to the group-by clause, which was the subject of my post. Tim Romano ___ sqlite-users mailing list sqlite-users@sqlite.org http://sqlite.org:8080/cgi-bin/mailman/listinfo/sqlite-users
Re: [sqlite] Min() ; was: Re: if exist
On Tue, Mar 9, 2010 at 10:46 AM, Tim Romanowrote: > On 3/9/2010 10:56 AM, Scott Hess wrote: >> On Tue, Mar 9, 2010 at 7:15 AM, Tim Romano wrote: >>> Of these three: >>> >>> select c from T where 1=2 // returns 0 rows >>> select min(c) from T where 1=2 // returns 1 row >>> select min(88,99) from T where 1=2 // returns 0 rows >>> >>> the only case that "threw" me is the second one, where a row is returned >>> despite a WHERE condition that should yield an empty set (or so I thought). >>> >> The first and last cases will run for each row in the WHERE clause. >> The second case is aggregating over all c, and will always return one >> row, even if the WHERE clause selects many rows, so it is consistent >> for it to return one row if the WHERE clause selects for no rows. >> It's as if you coded it like this: >> >> SELECT min(SELECT c FROM t WHERE ...) >> >> meaning the minimum of that set of inputs, and if that set is empty, >> there is no minimum, so you get a result of NULL, but not no result, >> if you see what I mean. > > Thanks for the replies, Scott and Igor and Pavel and Puneet. What I see > is that an aggregate function needs to partner with the GROUP BY clause > in order for nulls to be removed from the aggregated set. > > select min(c) from T where 1=2 > > returns 1 row that contains despite the presence of the aggregate > function > > and so > > select min(c) is null from T where 1 =2 > > returns true (1). But > > select min(c) from T where 1=2 > /group by/ foo > > returns no rows, presumably because the null value was removed from the > aggregated set. No, the null value is not removed, group-by groups the results, and you have no results, so there are no groups, so min(c) never comes up at all. When you run min(c) across the entire table, the table _does_ exist, though it might be empty, so min(c) has to have a result, and since there are no c, the result has to be NULL. [BTW, if you had a group-by, but no values are present for column c in that group of rows, min(c) would also be NULL for that group.] NULL means that there was a result, and the result was not a value, as distinct from not having a result at all. -scott ___ sqlite-users mailing list sqlite-users@sqlite.org http://sqlite.org:8080/cgi-bin/mailman/listinfo/sqlite-users
Re: [sqlite] Min() ; was: Re: if exist
On Tue, Mar 9, 2010 at 12:46 PM, Tim Romanowrote: > On 3/9/2010 10:56 AM, Scott Hess wrote: >> On Tue, Mar 9, 2010 at 7:15 AM, Tim Romano wrote: >> >>> Of these three: >>> >>> select c from T where 1=2 // returns 0 rows >>> select min(c) from T where 1=2 // returns 1 row >>> select min(88,99) from T where 1=2 // returns 0 rows >>> >>> the only case that "threw" me is the second one, where a row is returned >>> despite a WHERE condition that should yield an empty set (or so I thought). >>> >> The first and last cases will run for each row in the WHERE clause. >> The second case is aggregating over all c, and will always return one >> row, even if the WHERE clause selects many rows, so it is consistent >> for it to return one row if the WHERE clause selects for no rows. >> It's as if you coded it like this: >> >> SELECT min(SELECT c FROM t WHERE ...) >> >> meaning the minimum of that set of inputs, and if that set is empty, >> there is no minimum, so you get a result of NULL, but not no result, >> if you see what I mean. >> > > Thanks for the replies, Scott and Igor and Pavel and Puneet. What I see > is that an aggregate function needs to partner with the GROUP BY clause > in order for nulls to be removed from the aggregated set. > > select min(c) from T where 1=2 > > returns 1 row that contains despite the presence of the aggregate > function > > and so > > select min(c) is null from T where 1 =2 > > returns true (1). But > > select min(c) from T where 1=2 > /group by/ foo > > returns no rows, presumably because the null value was removed from the > aggregated set. > I don't know what "/group by/ foo" means. Is that something you tried and actually got no rows? If you did the following SELECT Min(c) AS foo FROM t WHERE 1=2 GROUP BY foo; you will get an error: SQL error: aggregate functions are not allowed in the GROUP BY clause If you did the following SELECT Min(c) AS c FROM t WHERE 1=2 GROUP BY foo; You will get an error: SQL error: no such column: foo Here is the rule -- if you are SELECT aggregate and non aggregate columns, then you should use GROUP BY for the non-aggregate columns. Assuming a table t(c, foo); the following is valid SELECT Min(c) AS minc, foo FROM t WHERE 1=2 GROUP BY foo; Min(), Max(), Count(), Sum(), etc. are aggregate functions, and act on the returned result set. Abs(), Glob(), Hex(), etc. are non-aggregate functions. Min(x,y,z...) behaves like a non-aggregate function. -- Puneet Kishor http://www.punkish.org Carbon Model http://carbonmodel.org Charter Member, Open Source Geospatial Foundation http://www.osgeo.org Science Commons Fellow, http://sciencecommons.org/about/whoweare/kishor Nelson Institute, UW-Madison http://www.nelson.wisc.edu --- Assertions are politics; backing up assertions with evidence is science === ___ sqlite-users mailing list sqlite-users@sqlite.org http://sqlite.org:8080/cgi-bin/mailman/listinfo/sqlite-users
Re: [sqlite] Min() ; was: Re: if exist
Tim Romanowrote: > select min(c) from T where 1=2 > > returns 1 row that contains despite the presence of the > aggregate function Not despite - _because_ of. If you didn't have the aggregate there, you'd get zero rows. > and so > >select min(c) is null from T where 1 =2 > > returns true (1). But > > select min(c) from T where 1=2 > /group by/ foo > > returns no rows, presumably because the null value was removed from > the aggregated set. No - because now there are no groups (as opposed to one group with zero rows as in the previous statement). It is somewhat illogical - I can't think of any logical reason why an empty resultset (without group by) should be treated as one group with zero rows, and not as zero groups (and, thus, why the first statement should produce one row). But that's the way all SQL engines I know about have behaved for as long as I can remember. Igor Tandetnik ___ sqlite-users mailing list sqlite-users@sqlite.org http://sqlite.org:8080/cgi-bin/mailman/listinfo/sqlite-users
Re: [sqlite] Min() ; was: Re: if exist
On 3/9/2010 10:56 AM, Scott Hess wrote: > On Tue, Mar 9, 2010 at 7:15 AM, Tim Romanowrote: > >> Of these three: >> >> select c from T where 1=2 // returns 0 rows >> select min(c) from T where 1=2 // returns 1 row >> select min(88,99) from T where 1=2 // returns 0 rows >> >> the only case that "threw" me is the second one, where a row is returned >> despite a WHERE condition that should yield an empty set (or so I thought). >> > The first and last cases will run for each row in the WHERE clause. > The second case is aggregating over all c, and will always return one > row, even if the WHERE clause selects many rows, so it is consistent > for it to return one row if the WHERE clause selects for no rows. > It's as if you coded it like this: > > SELECT min(SELECT c FROM t WHERE ...) > > meaning the minimum of that set of inputs, and if that set is empty, > there is no minimum, so you get a result of NULL, but not no result, > if you see what I mean. > Thanks for the replies, Scott and Igor and Pavel and Puneet. What I see is that an aggregate function needs to partner with the GROUP BY clause in order for nulls to be removed from the aggregated set. select min(c) from T where 1=2 returns 1 row that contains despite the presence of the aggregate function and so select min(c) is null from T where 1 =2 returns true (1). But select min(c) from T where 1=2 /group by/ foo returns no rows, presumably because the null value was removed from the aggregated set. Regards Tim Romano ___ sqlite-users mailing list sqlite-users@sqlite.org http://sqlite.org:8080/cgi-bin/mailman/listinfo/sqlite-users
Re: [sqlite] Min() ; was: Re: if exist
Tim Romanowrote: > Of these three: > > select c from T where 1=2 // returns 0 rows > select min(c) from T where 1=2 // returns 1 row > select min(88,99) from T where 1=2 // returns 0 rows > > > the only case that "threw" me is the second one, where a row is > returned despite a WHERE condition that should yield an empty set (or > so I thought). Aggregate functions work this way, yes. > Regarding your point about the GROUP BY clause -- I'm not sure what > you mean by "non-aggregate columns". Expressions in the SELECT list that don't mention aggregate functions. As in select x, min(y) from T; > Are you referring to a query > where one wants to find the minimum value in a given column for the > /entire/ table? > > select min(askingprice) from cars4sale > group by rowid //<= a group by is required here? A GROUP BY doesn't make sense here. Without GROUP BY, the whole table (more precisely, all the rows matching the WHERE clause, if any) is in one group, and minimum is calculated across that group (if the group is empty, min() produces null). With GROUP BY clause, every individual row is in its own separate group, and minimum is calculated for each row, which is rather pointless. Igor Tandetnik ___ sqlite-users mailing list sqlite-users@sqlite.org http://sqlite.org:8080/cgi-bin/mailman/listinfo/sqlite-users
Re: [sqlite] Min() ; was: Re: if exist
On Tue, Mar 9, 2010 at 9:56 AM, Scott Hesswrote: > On Tue, Mar 9, 2010 at 7:15 AM, Tim Romano wrote: >> Of these three: >> >> select c from T where 1=2 // returns 0 rows >> select min(c) from T where 1=2 // returns 1 row >> select min(88,99) from T where 1=2 // returns 0 rows >> >> the only case that "threw" me is the second one, where a row is returned >> despite a WHERE condition that should yield an empty set (or so I thought). > > The first and last cases will run for each row in the WHERE clause. > The second case is aggregating over all c, and will always return one > row, even if the WHERE clause selects many rows, so it is consistent > for it to return one row if the WHERE clause selects for no rows. > It's as if you coded it like this: > > SELECT min(SELECT c FROM t WHERE ...) > > meaning the minimum of that set of inputs, and if that set is empty, > there is no minimum, so you get a result of NULL, but not no result, > if you see what I mean. > That is a great explanation. Another way to think about it is to go from right to left. In first and third cases, the WHERE clause is true for 0 rows, and so SELECT is unable to return anything. In the second case also the WHERE clause returns 0 rows, but there is no Min defined for 0 rows, so a NULL is returned. Now, you may ask, how is Min(88,89) different from Min(c), and that is where the note from the docs I sent comes in. The Min(x,y..) form makes min() perform like a simple function such as Sin() or Left(), etc. But when given a single argument, Min() operates as an aggregate function if given only a single argument. Consider sqlite> SELECT Min(88,89) WHERE 1=2; sqlite> SELECT Min(88) WHERE 1=2; Min(88) -- sqlite> Note that Min(88) is returning a NULL row while Min(88,89) is not returning anything. > -scott > ___ > sqlite-users mailing list > sqlite-users@sqlite.org > http://sqlite.org:8080/cgi-bin/mailman/listinfo/sqlite-users > -- Puneet Kishor http://www.punkish.org Carbon Model http://carbonmodel.org Charter Member, Open Source Geospatial Foundation http://www.osgeo.org Science Commons Fellow, http://sciencecommons.org/about/whoweare/kishor Nelson Institute, UW-Madison http://www.nelson.wisc.edu --- Assertions are politics; backing up assertions with evidence is science === ___ sqlite-users mailing list sqlite-users@sqlite.org http://sqlite.org:8080/cgi-bin/mailman/listinfo/sqlite-users
Re: [sqlite] Min() ; was: Re: if exist
On Tue, Mar 9, 2010 at 7:15 AM, Tim Romanowrote: > Of these three: > > select c from T where 1=2 // returns 0 rows > select min(c) from T where 1=2 // returns 1 row > select min(88,99) from T where 1=2 // returns 0 rows > > the only case that "threw" me is the second one, where a row is returned > despite a WHERE condition that should yield an empty set (or so I thought). The first and last cases will run for each row in the WHERE clause. The second case is aggregating over all c, and will always return one row, even if the WHERE clause selects many rows, so it is consistent for it to return one row if the WHERE clause selects for no rows. It's as if you coded it like this: SELECT min(SELECT c FROM t WHERE ...) meaning the minimum of that set of inputs, and if that set is empty, there is no minimum, so you get a result of NULL, but not no result, if you see what I mean. -scott ___ sqlite-users mailing list sqlite-users@sqlite.org http://sqlite.org:8080/cgi-bin/mailman/listinfo/sqlite-users
Re: [sqlite] Min() ; was: Re: if exist
> sqlite> SELECT Min(m) AS m FROM t WHERE 1=2; > m > -- > sqlite> SELECT Min(m) FROM t; > Min(m) > -- > 88 Puneet, note that you probably missed one empty row of terminal output in the first query above and when there's no row returned sqlite3 command line utility doesn't print any headers information. Try this query to check things out: SELECT COUNT(*) FROM (SELECT Min(m) AS m FROM t WHERE 1=2). Pavel On Tue, Mar 9, 2010 at 8:04 AM, P Kishorwrote: > On Tue, Mar 9, 2010 at 6:18 AM, Tim Romano wrote: >> Wrapping a column in the min() function causes a query that returns no >> rows to return a row? >> >> select c from T where 1=2 // returns 0 rows > > The above is correct SQL, and the answer is correct. > >> select min(c) from T where 1=2 // returns 1 row > > You should be getting 0 rows; I do. What version of sqlite are you running? > > SQLite version 3.6.19 > Enter ".help" for instructions > Enter SQL statements terminated with a ";" > sqlite> CREATE TABLE t (m); > sqlite> INSERT INTO t VALUES (88); > sqlite> INSERT INTO t VALUES (89); > sqlite> SELECT * FROM t; > m > -- > 88 > 89 > sqlite> SELECT Min(m) AS m FROM t WHERE 1=2; > m > -- > sqlite> SELECT Min(m) FROM t; > Min(m) > -- > 88 > > >> select min(88,99) from T where 1=2 // returns 0 rows > > The above is correct SQL and the answer is correct. Per the docs, > "Note that min() is a simple function when it has 2 or more arguments > but operates as an aggregate function if given only a single > argument." > > Finally, note that when returning both aggregate and non-aggregate > columns, you should use the GROUP BY clause. I believe that SQLite > will return rows even without GROUP BY, but the answer may be > undependable. > >> >> Tim Romano >> > .. > > > -- > Puneet Kishor http://www.punkish.org > Carbon Model http://carbonmodel.org > Charter Member, Open Source Geospatial Foundation http://www.osgeo.org > Science Commons Fellow, http://sciencecommons.org/about/whoweare/kishor > Nelson Institute, UW-Madison http://www.nelson.wisc.edu > --- > Assertions are politics; backing up assertions with evidence is science > === > ___ > sqlite-users mailing list > sqlite-users@sqlite.org > http://sqlite.org:8080/cgi-bin/mailman/listinfo/sqlite-users > ___ sqlite-users mailing list sqlite-users@sqlite.org http://sqlite.org:8080/cgi-bin/mailman/listinfo/sqlite-users
Re: [sqlite] Min() ; was: Re: if exist
On Tue, Mar 9, 2010 at 7:34 AM, Pavel Ivanovwrote: >> sqlite> SELECT Min(m) AS m FROM t WHERE 1=2; >> m >> -- >> sqlite> SELECT Min(m) FROM t; >> Min(m) >> -- >> 88 > > Puneet, note that you probably missed one empty row of terminal output > in the first query above and when there's no row returned sqlite3 > command line utility doesn't print any headers information. Try this > query to check things out: SELECT COUNT(*) FROM (SELECT Min(m) AS m > FROM t WHERE 1=2). > > Yes, you are absolutely correct. > Pavel > > On Tue, Mar 9, 2010 at 8:04 AM, P Kishor wrote: >> On Tue, Mar 9, 2010 at 6:18 AM, Tim Romano wrote: >>> Wrapping a column in the min() function causes a query that returns no >>> rows to return a row? >>> >>> select c from T where 1=2 // returns 0 rows >> >> The above is correct SQL, and the answer is correct. >> >>> select min(c) from T where 1=2 // returns 1 row >> >> You should be getting 0 rows; I do. What version of sqlite are you running? >> >> SQLite version 3.6.19 >> Enter ".help" for instructions >> Enter SQL statements terminated with a ";" >> sqlite> CREATE TABLE t (m); >> sqlite> INSERT INTO t VALUES (88); >> sqlite> INSERT INTO t VALUES (89); >> sqlite> SELECT * FROM t; >> m >> -- >> 88 >> 89 >> sqlite> SELECT Min(m) AS m FROM t WHERE 1=2; >> m >> -- >> sqlite> SELECT Min(m) FROM t; >> Min(m) >> -- >> 88 >> >> >>> select min(88,99) from T where 1=2 // returns 0 rows >> >> The above is correct SQL and the answer is correct. Per the docs, >> "Note that min() is a simple function when it has 2 or more arguments >> but operates as an aggregate function if given only a single >> argument." >> >> Finally, note that when returning both aggregate and non-aggregate >> columns, you should use the GROUP BY clause. I believe that SQLite >> will return rows even without GROUP BY, but the answer may be >> undependable. >> >>> >>> Tim Romano >>> >> .. >> >> -- Puneet Kishor http://www.punkish.org Carbon Model http://carbonmodel.org Charter Member, Open Source Geospatial Foundation http://www.osgeo.org Science Commons Fellow, http://sciencecommons.org/about/whoweare/kishor Nelson Institute, UW-Madison http://www.nelson.wisc.edu --- Assertions are politics; backing up assertions with evidence is science === ___ sqlite-users mailing list sqlite-users@sqlite.org http://sqlite.org:8080/cgi-bin/mailman/listinfo/sqlite-users
Re: [sqlite] Min() ; was: Re: if exist
On Tue, Mar 9, 2010 at 6:18 AM, Tim Romanowrote: > Wrapping a column in the min() function causes a query that returns no > rows to return a row? > > select c from T where 1=2 // returns 0 rows The above is correct SQL, and the answer is correct. > select min(c) from T where 1=2 // returns 1 row You should be getting 0 rows; I do. What version of sqlite are you running? SQLite version 3.6.19 Enter ".help" for instructions Enter SQL statements terminated with a ";" sqlite> CREATE TABLE t (m); sqlite> INSERT INTO t VALUES (88); sqlite> INSERT INTO t VALUES (89); sqlite> SELECT * FROM t; m -- 88 89 sqlite> SELECT Min(m) AS m FROM t WHERE 1=2; m -- sqlite> SELECT Min(m) FROM t; Min(m) -- 88 > select min(88,99) from T where 1=2 // returns 0 rows The above is correct SQL and the answer is correct. Per the docs, "Note that min() is a simple function when it has 2 or more arguments but operates as an aggregate function if given only a single argument." Finally, note that when returning both aggregate and non-aggregate columns, you should use the GROUP BY clause. I believe that SQLite will return rows even without GROUP BY, but the answer may be undependable. > > Tim Romano > .. -- Puneet Kishor http://www.punkish.org Carbon Model http://carbonmodel.org Charter Member, Open Source Geospatial Foundation http://www.osgeo.org Science Commons Fellow, http://sciencecommons.org/about/whoweare/kishor Nelson Institute, UW-Madison http://www.nelson.wisc.edu --- Assertions are politics; backing up assertions with evidence is science === ___ sqlite-users mailing list sqlite-users@sqlite.org http://sqlite.org:8080/cgi-bin/mailman/listinfo/sqlite-users
[sqlite] Min() ; was: Re: if exist
Wrapping a column in the min() function causes a query that returns no rows to return a row? select c from T where 1=2 // returns 0 rows select min(c) from T where 1=2 // returns 1 row select min(88,99) from T where 1=2 // returns 0 rows Tim Romano On 3/9/2010 4:15 AM, Martin.Engelschalk wrote: > Hi, > > try this: > > select coalesce(min(length), 0) from t where id = ? > > Martin > > Andrea Galeazzi schrieb: > >> Hi All, >> I've got a table T made up of only two fields: INT id (PRIMARY KEY) and >> INT length. >> I need a statement in order to yield 0 when the key doesn't exist. At >> this moment the query is too simple: >> SELECT length FROM T WHERE id = ? >> Any idea about it? >> ___ sqlite-users mailing list sqlite-users@sqlite.org http://sqlite.org:8080/cgi-bin/mailman/listinfo/sqlite-users
Re: [sqlite] Min() ; was: Re: if exist
> Wrapping a column in the min() function causes a query that returns no > rows to return a row? Yes, it's SQL standard for aggregate functions (min, max, avg and count): without GROUP BY clause they always return one row. Pavel On Tue, Mar 9, 2010 at 7:18 AM, Tim Romanowrote: > Wrapping a column in the min() function causes a query that returns no > rows to return a row? > > select c from T where 1=2 // returns 0 rows > select min(c) from T where 1=2 // returns 1 row > select min(88,99) from T where 1=2 // returns 0 rows > > Tim Romano > > On 3/9/2010 4:15 AM, Martin.Engelschalk wrote: >> Hi, >> >> try this: >> >> select coalesce(min(length), 0) from t where id = ? >> >> Martin >> >> Andrea Galeazzi schrieb: >> >>> Hi All, >>> I've got a table T made up of only two fields: INT id (PRIMARY KEY) and >>> INT length. >>> I need a statement in order to yield 0 when the key doesn't exist. At >>> this moment the query is too simple: >>> SELECT length FROM T WHERE id = ? >>> Any idea about it? >>> > > ___ > sqlite-users mailing list > sqlite-users@sqlite.org > http://sqlite.org:8080/cgi-bin/mailman/listinfo/sqlite-users > ___ sqlite-users mailing list sqlite-users@sqlite.org http://sqlite.org:8080/cgi-bin/mailman/listinfo/sqlite-users
Re: [sqlite] Min() ; was: Re: if exist
On 3/9/2010 8:04 AM, P Kishor wrote: > >> select min(88,99) from T where 1=2 // returns 0 rows >> > The above is correct SQL and the answer is correct. Per the docs, > "Note that min() is a simple function when it has 2 or more arguments > but operates as an aggregate function if given only a single > argument." > > Finally, note that when returning both aggregate and non-aggregate > columns, you should use the GROUP BY clause. I believe that SQLite > will return rows even without GROUP BY, but the answer may be > undependable. > Of these three: select c from T where 1=2 // returns 0 rows select min(c) from T where 1=2 // returns 1 row select min(88,99) from T where 1=2 // returns 0 rows the only case that "threw" me is the second one, where a row is returned despite a WHERE condition that should yield an empty set (or so I thought). Regarding your point about the GROUP BY clause -- I'm not sure what you mean by "non-aggregate columns". Are you referring to a query where one wants to find the minimum value in a given column for the /entire/ table? select min(askingprice) from cars4sale group by rowid //<= a group by is required here? Regards Tim Romano ___ sqlite-users mailing list sqlite-users@sqlite.org http://sqlite.org:8080/cgi-bin/mailman/listinfo/sqlite-users