Sum all rows returning from SELECT statement - mysql

SELECT SUM(SELECT type.value
FROM type,item_type
WHERE item_type.type_id = type.id AND item_type.type_id IN (4,7)
GROUP BY type.id)
What's wrong with this query? I would like to sum all rows coming from the internal query.

You can't use SUM() function with subquerys. According to the manual the SUM() function returns the total sum of a numeric column. The way you were doing, was something like that: SELECT 1+50+30+10. Where is the table you were selecting the values? The sintax is:
SELECT SUM(column) FROM table
Take a look at:
http://www.w3schools.com/sql/sql_func_sum.asp
The correct way is
SELECT t.id, SUM(t.value)
FROM type as t,
INNER JOIN item_type as it
ON it.type_id = t.id
WHERE it.type_id IN (4,7)
GROUP BY t.id
Consider to use JOIN sintax instead of multiple tables: SQL left join vs multiple tables on FROM line?

You should learn to use proper join syntax and table aliases:
SELECT SUM(t.value)
FROM type t JOIN
item_type it
ON it.type_id = t.id
WHERE it.type_id IN (4,7);
If you want one row for each type.id, then you need a GROUP BY.
Your query doesn't work because subqueries are not allowed as arguments to aggregation functions. Even if they were, the context would be for a scalar subquery and your subquery is likely to return more than one row.

Just use SUM without internal query :
SELECT type.id, SUM(type.value)
FROM type,item_type
WHERE item_type.type_id = type.id AND item_type.type_id IN (4,7)
GROUP BY type.id

Related

Error in SQL query GROUP BY clause; sql_mode=only_full_group_by

Please help me with this SQL query; when I use a GROUP BY clause, I get this error from Mysql:
This is incompatible with sql_mode=only_full_group_by
I want different values on column: B.shopname.
SELECT
A.id,
COUNT(A.id),
A.idShop,
B.shopname
FROM
A
INNER JOIN
B ON A.idShop = B.id
GROUP BY
B.shopname
The GROUP BY columns are incompatible with the SELECT columns. Why? The query is trying to SELECT three unaggregated columns, A.id, A.idShop, and B.shopname. However, the GROUP BY only includes one of those.
The general recommendation is to add all unaggregated columns into the GROUP BY:
SELECT A.id, COUNT(A.id), A.idShop, B.shopname
FROM A INNER JOIN
B
ON A.idShop = B.id
GROUP BY A.id, A.idShop, B.shopname;
But I don't think this will do what you want. I am guessing that the COUNT() will always be 1. I suspect you want:
SELECT B.idShop, B.shopname, COUNT(*)
FROM A INNER JOIN
B
ON A.idShop = B.id
GROUP BY B.id, B.shopname;
Notes:
A.id is no longer in the SELECT. It is not appropriate because you want to count the values.
I doubt that A.id is ever NULL, so counting the non-NULL values of the column just clutters the query. COUNT(*) is clearer (although some folks prefer COUNT(1)).
It is better to have GROUP BY keys all be from the same table because it gives the optimizer more options.

How to join a derived table

I have a complex query which results in a table which includes a time column. There are always two rows with the same time:
The result also contains a value column. The value of two rows with the same time is always different.
I now want to extend the query to join the rows with the same time together. So my thought was to join the derived table like this:
SELECT A.time, A.value AS valueA, B.value as valueB FROM
(
OLD_QUERY
) AS A INNER JOIN A AS B ON
A.time=B.time AND
A.value <> B.value;
However, the JOIN A AS B part of the query does not work. A is not recognized as the derived table. MySQL is searching for a table A in the database and does not find it.
So the question is: How can I join a derived table?
You cannot join a single reference to a table (or subquery) to itself; a subquery must be repeated.
Example: You cannot even do
SELECT A.* FROM sometable AS A INNER JOIN A ...
The A after the INNER JOIN is invalid unless you actually have a real table called A.
You can insert the subquery's results into another table, and use that; but it cannot be a true TEMPORARY table, as those cannot be joined to themselves or referenced twice at all in almost any query. _By referenced twice, I mean joined, unioned, used as an "WHERE IN" subquery when it is already referenced in the FROM.
If nothing else distinguishes the rows, you can just use aggregation to get the two values:
select time, min(value), max(value)
from (<your query here>) a
group by time;
In MySQL 8+, you can use a cte:
with a as (
<your query here>
)
select a1.time, a1.value, a2.value
from a a1 join
a a2
on a1.time = a2.time and a1.value <> a2.value;

Two select statements on same table and get Count(*)

Im trying to do two queries on the same table to get the Count(*) value.
I have this
SELECT `a`.`name`, `a`.`points` FROM `rank` AS a WHERE `id` = 1
And in the same query I want to do this
SELECT `b`.`Count(*)` FROM `rank` as b WHERE `b`.`points` >= `a`.`points`
I tried searching but did not find how to do a Count(*) in the same query.
Typically you would not intermingle a non aggregate and aggregate query together in MySQL. You might do this in databases which support analytic functions, such as SQL Server, but not in (the current version of) MySQL. That being said, your second query can be handled using a correlated subquery in the select clause the first query. So you may try the following:
SELECT
a.name,
a.points,
(SELECT COUNT(*) FROM rank b WHERE b.points >= a.points) AS cnt
FROM rank a
WHERE a.id = 1;
As I understand from the question, you want to find out in a table for a given id how many rows have the points greater than this row. This can be achieved using full join.
select count(*) from rank a join rank b on(a.id != b.id) where a.id=1 and b.points >= a.points;

Rule to put fields in select clause when joining multiple tables and query has group by clause

I am learning sql join and would like to clear an idea.
I understand that all the select columns should present in group by clause.
For example,
select a, b
from table_one
group by a,b;
I want to join two tables, something similar to this -
select table_one.a
from table_one, table_two
where table_one.id = table_two.id
group by table_two.c
The question is - should I put table_two.c in select since it is in group by clause?
A group by clause is neede, if you have an analytical function. Simple example:
select order_date, sum(orders)
from orders_table
group by order_date;
It makes logically sense, to group only on columns, that are also in your select clause. Otherwise, you could have weird data for the end user. Example:
select order_date, sum(orders)
from orders
group by country. order_date;
This would give you a separate row for each date and country, but you only see the date in the result.
So the simple rule ist: add all columns to the group by statement that do not use an analytical function (i.e. min(), max(), avg(), count()) and do not use columns in the group by statement that are not also present in the select clause.
This does not change when joining. Grouping is completely independant from joins. THe only thing that matters is, which columns you use.
When joining tables you can use the JOIN-statements instead
Example with your query:
SELECT t1.a
FROM table_one t1 /*(t1 is the alias for the table)*/
INNER JOIN table_two t2 ON t1.id = t2.id
GROUP BY t2.c
You don't need to put the t2.c in your select, if you don't specifically want it in the results. Since you are only selecting t1.a, that is all you're gonna get.
Another answer here on SO regarding GROUP BY is worth reading aswell. :)
https://stackoverflow.com/a/1591976/1025823

COUNT(*) returning multiple rows instead of just one

Why does COUNT() return multiple rows when I just need the total count of how many rows my query generates?
Should return 1078.
The COUNT() is working as expected. When you put a group by clause, the count() gives you the result for GROUP BY. If you wish to get the count of rows in a query that includes group by, use it as a subquery instead.
Something like:
SELECT COUNT(*) FROM (SELECT * FROM `table`
GROUP BY `column1`) AS `a`
Well, simple answer. Don't GROUP BY if you don't need groups.
Either use COUNT(DISTINCT articles.company) without GROUP BY or keep the the GROUP BY and wrap the whole query in a SELECT COUNT(*) FROM (...) AS data, if you want to count the groups.
Do not use group by, it will count the number of each group.
Write the above query as subquery then it will give proper result and dont use group by
select count(*) from (select articles.id from 'contract_prices' left join 'articles' on
(arcticles.id = contract_prices.article)
where 'contract_to' >= curdate()
)