What is the difference between these two Postgres query - postgresql-9.1

Select sum(a),sum(b)
from table
where c like '234%'
and time > '2013-12-31'
and d = 'hello';
Then I explicitly calculate the value of sum(a)-sum(b).
Select sum(a-b)
from table
where c like '234%'
and time > '2013-12-31'
and d = 'hello';
As both of these queries are giving different results.
By Doing an EXPLAIN ANALYSE on both of these queries, I see that second query has removed more rows by Filter conditions.
I am not able to find an explanation for this.

The difference is likely due to nulls existing within the data. If you had "a" as 3 and "b" as null then you'd receive a null result on something like:
select 3 - null;
Doing the sums individually will allow each to increment to the actual sums skipping nulls only for that individual column not the entire row and likely be more of what you're looking for.

Related

Ordering SQLite table by sum of two columns

I have a database that has two integer columns, and I'm trying to find a way to select the top 'x' amount of rows with the highest sums of these two columns. I'm trying to eliminate the need of creating a third column that stores the sum of the two, unless there's a way to to automatically update this column every time one of the other two are altered. I'm using SQLite by the way, as I know there are some slight differences here and there between SQL/SQLite syntax.
Any help is appreciated.
Something like
SELECT a, b
FROM yourtable
ORDER BY a + b DESC
LIMIT :x
should do it.

Why is SQLite query on two indexed columns so slow?

I have a table with around 65 million rows that I'm trying to run a simple query on. The table and indexes looks like this:
CREATE TABLE E(
x INTEGER,
t INTEGER,
e TEXT,
A,B,C,D,E,F,G,H,I,
PRIMARY KEY(x,t,e,I)
);
CREATE INDEX ET ON E(t);
CREATE INDEX EE ON E(e);
The query I'm running looks like this:
SELECT MAX(t), B, C FROM E WHERE e='G' AND t <= 9878901234;
I need to run this queries for thousands of different values of t and was expecting each query to run in a fraction of a second. However, the above query is taking nearly 10 seconds to run!
I tried running the query plan but only get this:
0|0|0|SEARCH TABLE E USING INDEX EE (e=?)
So this should be using the index. With a binary search I would expect worse case only 26 tests, which I would be pretty quick.
Why is my query so slow?
Each table in a query can use one index. Since your WHERE clause looks at multiple columns, you can use a multi-column index. For these, all but the last column used from the index has to test for equality; the last one used can be used for greater than/less than.
So:
CREATE INDEX e_idx_e_t ON E(e, t);
should give you a boost.
For further reading about how Sqlite uses indexes, the Query Planner documentation is a good introduction.
You're also mixing an aggregate function (max(t)) and columns (B and C) that aren't part of a group. In Sqlite's case, this means that it will pick values for B and C from the row with the maximum t value; other databases usually throw an error.

In SQLite3 how to group by those having no certain values?

A table named "example" is like this:
enter image description here
I would like to SELECT Name FROM example GROUP BY NAME. But at the same time, if anyone's value contains X, then that one should be excluded from the result. In the "example" table, A has three values and one of them is X so A should be excluded from the result. So does B.
The result produced by SQL clauses should be:
C
D
Could anyone help me write corresponding SQL clauses so that I can get the result I want?
Thank you!!
I tried to write something like this:
SELECT Name FROM example WHERE Value <> X GROUP BY NAME.
It didn't work because A and B still have other values which prevent them from being excluded. I just have no idea of what else I can do. I'm very new in SQL.
A comparison results in either 0 or 1.
So taking the largest result in a group shows whether there is a match in the group:
SELECT Name
FROM Example
GROUP BY Name
HAVING MAX(Value = 'X') = 0;

Access 2010 query expression syntax help please

I'm sure this is an elementary answer but I cannot see the forest for the trees at the moment, any help would be appreciated.
I'm building a query in which I need to have the results fill TRUE if there is any filled value in the table that is queried.
One approach is that you convert the field your checking into a 1 or 0 based on whether it contains data or not.
So a table:
ID, Field1
1 , "A"
2 , ""
3 , "C"
You could then have a query:
SELECT Sum(IIf(Len(Trim([Field1]))>0,1,0)) AS CompletedFields FROM Table1;
Which will give you a count of the completed fields, in this case 2, which will equate to True as boolean.
Obviously you need to adjust the Len(Trim([field]))>0 to match your rule that determines if a field is complete or not.
This also gives the actual number of completed (and therefore uncompleted) rows, rather than a blunt true/false.

sqlite subqueries with group_concat as columns in select statements

I have two tables, one contains a list of items which is called watch_list with some important attributes and the other is just a list of prices which is called price_history. What I would like to do is group together 10 of the lowest prices into a single column with a group_concat operation and then create a row with item attributes from watch_list along with the 10 lowest prices for each item in watch_list. First I tried joins but then I realized that the operations where happening in the wrong order so there was no way I could get the desired result with a join operation. Then I tried the obvious thing and just queried the price_history for every row in the watch_list and just glued everything together in the host environment which worked but seemed very inefficient. Now I have the following query which looks like it should work but it's not giving me the results that I want. I would like to know what is wrong with the following statement:
select w.asin,w.title,
(select group_concat(lowest_used_price) from price_history as p
where p.asin=w.asin limit 10)
as lowest_used
from watch_list as w
Basically I want the limit operation to happen before group_concat does anything but I can't think of a sql statement that will do that.
Figured it out, as somebody once said "All problems in computer science can be solved by another level of indirection." and in this case an extra select subquery did the trick:
select w.asin,w.title,
(select group_concat(lowest_used_price)
from (select lowest_used_price from price_history as p
where p.asin=w.asin limit 10)) as lowest_used
from watch_list as w

Resources