count(*) returning negative value - mysql

I have a strange problem and something that I haven't come across before. I have a mysql query like the one below
SELECT COUNT( * ) AS total_count FROM postcodes WHERE prefix='M1';
My query matches one row so I am expecting the value of total_count to be 1. However instead it is returning -1. Does anyone know why if would be returning a negative value?

According to this bug report, you need to run REPAIR TABLE.

Did you use ExecuteNonQuery instead of ExecuteScalar? Or in more general terms, did you read the row count instead of the result [in the first column of the first row]?
That's what I did to get a -1. Oops.

Related

How does select query works

I need to return value in preference order, if the value starts with a it should be returned first, if it does not exist we return the value which starts with b.
SELECT value FROM table one
WHERE value LIKE a% OR value LIKE b%
OR value LIKE c% OR value LIKE d% LIMIT 1;
Does the query return the value in order, as in the value which starts with 'a' should be returned and if a value does not exist then the value starting with 'b' should be returned and so on.
The stuff in your WHERE clause does not determine the order of rows in your result set. Unless your query includes an ORDER BY clause the order of rows is unpredictable. The server is free to return the rows to you in any convenient order, depending on who knows what?
Many programmers fall into a trap here. We experiment with writing the query different ways on tiny test datasets and see different orders, so we get lulled into thinking the order is predictable. Then, our code goes into production on big, and hopefully growing data sets, and BAM! suddenly the server starts using a different query plan because the data grew, and the rows come back in a different order, and some program starts to fail. Usually in the middle of the night.
It would be great if servers returned rows in random order when we don't give an ORDER BY clause. That way we'd have a chance of catching this kind of bug in testing.
If you find yourself writing a query with no ORDER BY, be afraid. Stop and think about unpredictable ordering.
Try with something like this
SELECT *
FROM [Table]
ORDER BY
CASE
WHEN [Value] like 'a%' THEN 1
WHEN [Value] like 'b%' THEN 2
WHEN [Value] like 'c%' THEN 3
ELSE 99 END

SELECT COUNT with LIKE gives strange result

I have a MYSQL-database with a table that has a mediumtext column. When trying to count the number of rows that has a specific word within that column, I get some strange result.
When I do this;
SELECT COUNT(*) AS antal FROM ot_pages where otp_ocr_raw LIKE '%vass%'
I get a count of around 860.
If I instead do a simple SELECT with the same question, like this:
SELECT * FROM ot_pages where otp_ocr_raw LIKE '%vass%'
I get a recordset with 70 rows back. Why is that? What would a correct SELECT COUNT-query look like to get a count of just 70?
Ok, I found the solution. The query contained letters like ÅÄÖ.
When I preformed a ordinary SELECT-query, those letters where correctly interpreted. But when doing a SELECT COUNT() those letters seems to have been interpreted by MySQL as AAO instead, hence giving a higher count than actual rows in the recordset.
The solution was to use utf8mb4 as charset, both in the script and the actual column. Now everything seems to work.

MySQL : Count returning double the number of entries when using distinct

So I do a count like so
select distinct count(prod.id) from product as prod....
I get back 175590
I do a select like so
select distinct prod.id from product as prod.... (rest of the query is exactly the same)
and I limit it. Now if I limit the query to return anything over the half way point it returns nothing. It appears as if count is returning double the number of entries each time.
Does anyone know of anything that may be causing this?
Thanks
Tracey
The DISTINCT keyword tells MySQL to strip the duplicate rows from the result set. Because SELECT COUNT(prod.id) returns a single row (I guess this, I cannot tell for sure until I see the complete query), adding DISTINCT in front of COUNT() does not change its behaviour in any way.
What you probably want is SELECT COUNT(DISTINCT prod.id) and that's a totally different thing. It removes the duplicate values of prod.id before counting them.
Your first query is counting how many prod.id's there are.
Your second query is showing all distinct prod.id's.
This is quite different.
If you were to do the second query without the distinct key word the number would be the same.

Rails ActiveRecord "maximum(:column)" ignores order

I am trying to retrieve the maximum value of a column using ActiveRecord, but after I order and limit the values.
My query is:
max_value = current_user.books.order('created_at DESC').limit(365).maximum(:price)
Yet the resulting query is:
(243.0ms) SELECT MAX(`books`.`price`) AS max_id FROM `books` WHERE `books`.`user_id` = 2 LIMIT 365
The order is ignored completely and as a result the maximum value comes from the first 365 records instead of the last 365 records.
There's a curious line in the active record code (active_record/relation/calculations.rb) which removes the ordering. I say curious because it refers specifically to postgres:
# Postgresql doesn't like ORDER BY when there are no GROUP BY
relation = reorder(nil)
You should be able to use pluck to achieve what you want. It can select a single attribute which can be a reference to an aggregate function:
q = current_user.books.order('created_at DESC').limit(365)
max_value = q.pluck("max(price)").first
pluck will return an array of values so you need the first to get the first one (and only one in this case). If there are no results then it will return nil.
According to the rails guides maximum returns the maximum value of your table for this field so I suppose Active Records tries to optimize your query and ends up messing up with the order of executing your chained methods.
Could you try: First query the 365 rows you want, and then get the maximum?
max_value = (current_user.books.order('created_at DESC').limit(365)).maximum(:price)
I have found the solution thanks to #RubyOnRails on freenode:
max_value = current_user.books.order('created_at DESC').limit(365).pluck(:price).max
Of course the drawback is that this will grab all 365 prices and calculate the max locally. But I'll survive.
Best and the most effective way is to do subquery .. do something like this ...
current_user.books.where(id: current_user.books.order('created_at DESC').limit(365)).maximum(:price)

MySQL Error Message: Subquery Returns More than 1 Row

Would you help me to fix this, please:
SELECT
(SELECT AES_DECRYPT(cryptoword, SHA2('DatabaseEncryption1', 512)) FROM file_tree) AS cryptoword1,
(SELECT AES_DECRYPT(name, SHA2(cryptoword1, 512)) FROM file_tree) AS name;
As the topic says, I get error saying that my subquery returns more than 1 row. What I look for to achieve is:
Get the cryptoword for the particular database record.
Use that cryptoword to decrypt the rest of the record.
Repeat the process for all the table records/multiple records satisfying WHERE condition, which I can add later
My query works, if I use the query for one record only. However, I need to get multiple records within from the table. Every record has its own cryptoword, which is different per each row. My task is therefore to get the cryptoword for particular record, and to use that one to decrypt the rest of the record. I need to repeat this process for all the table records.
Because of performance reasons, it all needs to be formatted within one query.
Thank you in advance.
Work out the value of cryptoword1 in a sub-query, then you can reuse the result to work out the value of name in the outer query.
SELECT
cryptoword1,
AES_DECRYPT(name, SHA2(cryptoword1, 512)) AS name
FROM
(
SELECT
AES_DECRYPT(cryptoword, SHA2('DatabaseEncryption1', 512)) AS cryptoword1,
name
FROM
file_tree
)
AS sub_query
Subqueries in the select statement must evaluate to a single value, or else you will get this error. This makes sense since you are looking to fill the value for one field.