MySQL: How to optimize result of SUM of fields? - mysql

I have this query:
SELECT name, SUM(count_1 + count_2 + count_3 + count_4 + count_5 + count_6) AS Total
FROM my_table
Is there a way to add these values count_1 + count_2 + count_3 + count_4 + count_5 + count_6 and so on.. more efficiently? MySQL keeps crashing for me when I add huge numbers of fields.

Regardless of whether the db design is right or wrong if you use an aggregation function you should use group by
SELECT name, SUM(count_1 + count_2 + count_3 + count_4 + count_5 + count_6) AS Total
FROM my_table
GROUP BY name

Related

Use a column created using AS to do aggregate functions

Can MySQL detect the columns created using AS?
Example;
SUM( Mark1 + Mark2) AS '2022_SUM'
SUM( Mark3 + Mark4) AS '2021_SUM'
(2022_SUM + 2021_SUM) AS 'SUM1'
It hits unknown column in field list.
Just write:
SELECT
SUM(Mark1 + Mark2) as '2022_SUM',
SUM(Mark3 + Mark4) as '2021_SUM',
SUM(Mark1 + Mark2) + SUM(Mark3 + Mark4) as 'SUM1'
FROM someTableName
OR
SELECT
2022_SUM,
2021_SUM,
2022_SUM + 2021_SUM as 'SUM1'
FROM (
SELECT
SUM(Mark1 + Mark2) as '2022_SUM',
SUM(Mark3 + Mark4) as '2021_SUM'
FROM someTableName
) x

MySQL issue with NULL values

I have a table with fields: country_code, short_name, currency_unit, a2010, a2011, a2012, a2013, a2014, a2015. a2010-a2015 fields are type of double.
How do I make a query which orders the results by average of fields a2010-a2015, keeping in mind that these fields might have NULL value?
I tried this code and it did not work (returns a mistake, which tells there is something wrong in ORDER BY part. mistake was saying something about coumn names and GROUP BY). The logic is: ORDER BY ((A)/(B)) where A - sum of not NULL fields and B - count of not NULL fields.
Any ideas?
(if important, the code is going to be used in BigInsights environment)
SELECT country_code, short_name, currency_unit, a2010, a2011, a2012,
a2013, a2014, a2015
FROM my_schema.my_table
WHERE Indicator_Code = 'SE.PRM.TENR'
ORDER BY
(
(
Coalesce(a2010,0) + Coalesce(a2011,0) + Coalesce(a2012,0)
+Coalesce(a2013,0) + Coalesce(a2014,0) + Coalesce(a2015,0)
)
/
(
COUNT(Coalesce(a2010)) + COUNT(Coalesce(a2011)) + COUNT(Coalesce(a2012))
+ COUNT(Coalesce(a2013)) + COUNT(Coalesce(a2014)) +
COUNT(Coalesce(a2015))
)
) DESC;
use MySQL ifnull
IFNULL(expression_1,expression_2)
in your query :-
IFNULL(
(
COUNT(Coalesce(a2010)) + COUNT(Coalesce(a2011)) + COUNT(Coalesce(a2012))
+ COUNT(Coalesce(a2013)) + COUNT(Coalesce(a2014)) +
COUNT(Coalesce(a2015))
),
1
)

Why adding SUM changes the number of retrieved rows?

I have this sql which gives me 6 rows without SUM clause (sur can give more if condition is true)
SELECT id, prodname, prodid, st_date, montant, tvaval, quantite, status, factureno
FROM StockData WHERE " + VenteWhere + " ORDER BY " + Order_by + " " + SortDir + "
PS: VenteWhere, Order_by abd SortDir are the variables.
BUt when I add SUM(quantite) I get only one row. Is there a way to have 6 rows data and the sum of 6 rows or I have to do another query for getting it
I think you can use
SELECT id, prodname, prodid, st_date, montant, tvaval, SUM(quantite), status, factureno
FROM StockData
WHERE " + VenteWhere + "
ORDER BY " + Order_by + " " + SortDir + "
GROUP BY xxxxx
Where xxxxx represents the variable you want to group by per row.
Summing will remove the rows its sums over and only display the sum itself. So you have to group by some variable to make it split the results over that variables 'occurence'

finding maximum data from multiple rows

Below is what I have
++++++++++++++++++++++++
+ id + field1 + field2 +
++++++++++++++++++++++++
+ 1 + 1 + +
+ 1 + 23 + +
+ 1 + + 1 +
+ 1 + + 33 +
+ 2 + 55 + +
+ 2 + + 2 +
+ 2 + + 23 +
++++++++++++++++++++++++
What I want is
++++++++++++++++++++++++
+ id + field1 + field2 +
++++++++++++++++++++++++
+ 1 + 23 + 33 +
+ 2 + 55 + 23 +
++++++++++++++++++++++++
I want to combine the rows (with greatest data) and show data for user in one row against multiple rows like I have in table.
Any idea how to do it?
Note : I don't have any row who have data for all fields. Only 1 data in one row and two or more rows per user.
I tried with
SELECT id, GROUP_CONCAT(MAX(field1)), GROUP_CONCAT(MAX(field2)) from myTable
GROUP BY id;
but its giving error as
Invalid use of group function:
data at sqlfiddle
This question is bit advanced to my earlier question, showing data in one row (from multiple rows)
SELECT id, MAX(field1), MAX(field2) FROM myTable GROUP BY id;
This simple query should do the trick.
SELECT id, MAX(field1), MAX(field2)
FROM myTable
GROUP BY id;
it groups all the rows with the same id and selects the maximum value within each group for each column

I need help finding the average number out of 60 columns, where the columns number does not equal 0

We have 2500 products on our site, ranked between 60 different categories. Our DB scheme is 61 columns, labled "product_id", and then the categories: "category_1", "category_2"... "category_60", and 2500 rows, one for each product. If a product is not ranked in a specific cateogry, that corresponding field is marked "0". If it is ranked, the field is an INT with whatever rank it is: "1" is 1st, "2" is second, etc.
Usually products are only ranked in 2-3 categories, so there are 57+ columns with a "0" in the field. My current query is:
mysql_query("SELECT AVG(category_1 + category_2 + category_3 + category_4 + category_5 + category_6 + category_7 + category_8 + category_9 + category_10 + category_11 + category_12 + category_13 + category_14 + category_15 + category_16 + category_17 + category_18 + category_19 + category_20 + category_21 + category_22 + category_23 + category_24 + category_25 + category_26 + category_27 + category_28 + category_29 + category_30 + category_31 + category_32 + category_33 + category_34 + category_35 + category_36 + category_37 + category_38 + category_39 + category_40 + category_41 + category_42 + category_43 + category_44 + category_45 + category_46 + category_47 + category_48 + category_49 + category_50 + category_51 + category_52 + category_53 + category_54 + category_55 + category_56 + category_57 + category_58 + category_59 + category_60) as 'cat_avg' FROM products.rankings WHERE product_id = '$product_id'");
With this, I'm just getting the sum of the columns, not the AVG. Maybe this has something to do with selecting rows instead of columns, I'm not sure. I tried SUM as well, instead of AVG, same thing.
I'm not really sure where to go from here. What i would like is the Average ranking across all columns for one product, where the column doesn't equal 0. So if a product_id 123 is ranked 7, 9 and 11, and then the other 57 columns are 0, the average returned would be 9 ((7+9+11)/3), not .45 ((7+9+11+0+0+0....+0))/60)
Note: I did not design this DB, I'm sure there is a better way to design it, but at this point it's too deeply integrated to change up quickly.
This may be a lot of stress on the query, but I don't know many other ways to do this, given the schema you have to work with.
One option is to sub-query the columns and union them, where the given columns are not 0:
SELECT AVG(
SELECT *
FROM (
SELECT category_1 AS category FROM table
UNION
SELECT category_2 AS category FROM table
UNION
...
) cats
WHERE category <> 0
)
FROM products.rankings
WHERE product_id = '$product_id'
It probably makes more sense to do this math within the page (assuming PHP given the query decorations) and on a per-row basis. Doing the above will put a lot of strain on the server depending the number of rows we're talking.
Restructured the whole DB... wasn't as bad as I though, just did a bunch of MySQL queries/updates that got me what I needed. Strained the server for a few hours, but it was well worth it in the end.