MySQL issue with NULL values - mysql

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
)

Related

MySQL: How to optimize result of SUM of fields?

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

Sort MySQL results by a column with several values separated by a period

I suspect this may have already been asked, but I'm not sure how to phrase the question so that SO search engine picks it up.
I have a column called TCID, which contains values in this format:
1.A.1.1.1
4.A.1.1.1
2.B.1.1.10
2.B.1.1.2
...
There are 5 units in this TCID, separated by periods. I want the position to the left to take the highest priority, and then finally the last digit is the lowest priority.
So it would sort like this:
1.A.1.1.1
2.B.1.1.2
2.B.1.1.10
4.A.1.1.1
Here is the query I have so far. It almost works, but the last position is not getting sorted.
SELECT *
FROM system
WHERE cluster = \"$tc_name\"
ORDER BY CAST(SUBSTR( SUBSTRING_INDEX(tcid,'.',1) , 1 ) AS UNSIGNED),
SUBSTR( SUBSTRING_INDEX(tcid,'.',2) , LENGTH( SUBSTRING_INDEX(tcid,'.',1)) + 2 ),
CAST(SUBSTR( SUBSTRING_INDEX(tcid,'.',3) , LENGTH( SUBSTRING_INDEX(tcid,'.',2)) + 2 ) AS UNSIGNED),
CAST(SUBSTR( SUBSTRING_INDEX(tcid,'.',4) , LENGTH( SUBSTRING_INDEX(tcid,'.',3)) + 2 ) AS UNSIGNED)
Can anyone help me fix this or suggest a better way to do this?
There are obviously better ways to store this information in the database, such as storing the values in separate fields. However, it's not always possible to change the code base to do such things.
But I believe you just need to add the final order by to your query in order to for it to work as expected;
SELECT *
FROM system
WHERE cluster = "<some search term>"
ORDER BY CAST(SUBSTR( SUBSTRING_INDEX(tcid,'.',1) , 1 ) AS UNSIGNED),
SUBSTR( SUBSTRING_INDEX(tcid,'.',2) , LENGTH( SUBSTRING_INDEX(tcid,'.',1)) + 2 ),
CAST(SUBSTR( SUBSTRING_INDEX(tcid,'.',3) , LENGTH( SUBSTRING_INDEX(tcid,'.',2)) + 2 ) AS UNSIGNED),
CAST(SUBSTR( SUBSTRING_INDEX(tcid,'.',4) , LENGTH( SUBSTRING_INDEX(tcid,'.',3)) + 2 ) AS UNSIGNED),
CAST(SUBSTR( SUBSTRING_INDEX(tcid,'.',5) , LENGTH( SUBSTRING_INDEX(tcid,'.',4)) + 2 ) AS UNSIGNED);
Please see this sqlfiddle to check
Just for fun...
SELECT *
FROM
(
SELECT '1.A.1.1.1' x
UNION ALL
SELECT '4.A.1.1.1'
UNION ALL
SELECT '2.B.1.1.10'
UNION ALL
SELECT '2.B.1.1.2'
) a
ORDER BY
INET_ATON(CONCAT(MID(x,1,1),MID(x,4,1000)));

Mysql delete duplicate base on email but keep the longest row-sum-length record

I have this code for deleting duplicate based on email and keep larget id record:
DELETE FROM mytable
WHERE id NOT IN (SELECT *
FROM (SELECT MAX(n.id)
FROM mytable n
GROUP BY n.email) x)
Now I write this code for base on email but keep the longest row-sum-length record:
DELETE FROM mytable
WHERE (char_length(firstname) + char_length(lastname) + char_length(location) + char_length(address)) NOT IN (SELECT *
FROM (SELECT MAX(char_length(n.firstname) + char_length(n.lastname) + char_length(n.location) + char_length(n.address))
FROM mytable n
GROUP BY n.email) x)
the weird thing is, it work for a small table, but for my large table, it just run a sec and show nothing effect. Can anyone tell me where did I do wrong?
Your approach is quite dangerous. It might work for ids, but not for lengths which could be in common across different rows. Instead, use a join:
DELETE t
FROM mytable t JOIN
(SELECT email,
(char_length(firstname) + char_length(lastname) +
char_length(location) + char_length(address)
) as len
FROM mytable
GROUP BY email
) tt
ON t.email = tt.email
WHERE (char_length(t.firstname) + char_length(t.lastname) +
char_length(t.location) + char_length(t.address)
) <> tt.len;

oledb command not fetching values

through following query i trying to merge three things parEmail , parEmployeeLogin , and parStaffID
now in the case one is null i get whole NameValue null .
SELECT (parFirstname +' '+ parSurname) AS NAME,
(parEmail +','+ parEmployeeLogin +','+ parStaffID) AS NameValue
FROM [tblParticipants]
where parFirstname Is Not Null
ORDER BY parFirstname
NameValue only have data in it if all three fields have data, it's fetching NAME properly....i am using this to get data out of Access file..what changes should be done in this oledb query..
NULL + anything = NULL. You've prevented partFirstName from being NULL with your WHERE clause, but if either of the other two columns is NULL, the entire result is NULL.
You'll have to either use IIF to provide alternate values for NULL columns, or change your WHERE to handle multiple NULL columns. (Untested) query for first option (don't have Access on this machine):
SELECT
partFirstName + ' ' + IIF(IsNull(parSurName), '<None>', parSurName) as Name,
IIF(IsNull(parEMail), '<No Mail>', parEMail) + ', ' +
IIF(IsNUll(parEmployeeLogin), '<No Login>', parEmployeeLogin) + ', ' +
IIF(IsNull(parStaffID), '<No ID>', parStaffID) as NameValue
FROM
[tblParticipants]
WHERE
parFirstName IS NOT NULL
ORDER BY
parFirstname

MySQL count (and sum) fields in multiple columns where 'not empty'

I'm using this MySQL query
SELECT COUNT(pros_a) + COUNT(pros_b) + COUNT(pros_c) + COUNT(pros_d) + COUNT(pros_e) AS pros_total FROM my_table WHERE contentid = 'id'
to count and sum fields in each column. But this returns ALL fields (full and empty). I want to count only filled fields, excluding empty fields. How can I do that? Just a little bit... confused! :)
Any help would be very appreciated!
Thanks
EDIT:
my_table
pros_a pros_b pros_c pros_d pros_e
------- ------ ------ ------ ------
good (empty) good good (empty)
expected result
pros_total
----------
3
The COUNT(column) function does not count fields that are NULL. It counts empty (zero-length) strings though.
You can change these into:
COUNT( CASE WHEN column <> '' THEN column END )
or:
SUM(column <> '')
The last works in MySQL because TRUE is evaluated as 1 and FALSE as 0.
SELECT COUNT(DISTINCT pros_a) + COUNT(DISTINCT pros_b) + COUNT(DISTINCT pros_c) + COUNT(DISTINCT pros_d) + COUNT(DISTINCT pros_e) FROM my_table WHERE contentid = 'id'
The above one should work.
Use where condition for empty fields, for example WHERE pros_a != '' or pros_a != '0' if is NULL. pros_a != '' AND pros_b != ''