Getting Lost Connection on a Specific Query - mysql

I'm getting a 2013 Lost Connection to MySQL server During Query on MySQL hosted on an AWS instance. The query below is the only one that causes this error (other queries run fine), and this query also runs with no issues on my Synology Docker container running MySQL. The only unique thing I have identified is that this query uses a CTE and the others that run successfully do not.
The AWS MySQL is 8.0.23 and the NAS Docker MySQL is 8.0.28.
I have checked the first things such as max connections, timeouts, etc and the values in use for the AWS instance are the same or higher than the settings on the NAS Docker instance. I have also tried a smaller data table and reorganizing the data table to weed out the possibility of data corruption.
I have been searching for a couple of days and have not been able to find any hints on what the issue is.
Does anyone here have any suggestions about where I should look next? Thanks!
USE ce_test;
SET #lowlim = 0;
SET #upplim = 0;
with orderedList AS (
SELECT
576_VMC_Sol_Savings_Pct,
ROW_NUMBER() OVER (ORDER BY 576_VMC_Sol_Savings_Pct) AS row_n
FROM vmctco
),
quartile_breaks AS (
SELECT
576_VMC_Sol_Savings_Pct,
(
SELECT 576_VMC_Sol_Savings_Pct AS quartile_break
FROM orderedList
WHERE row_n = FLOOR((SELECT COUNT(*) FROM vmctco)*0.75)
) AS q_three_lower,
(
SELECT 576_VMC_Sol_Savings_Pct AS quartile_break
FROM orderedList
WHERE row_n = FLOOR((SELECT COUNT(*) FROM vmctco)*0.75) + 1
) AS q_three_upper,
(
SELECT 576_VMC_Sol_Savings_Pct AS quartile_break
FROM orderedList
WHERE row_n = FLOOR((SELECT COUNT(*) FROM vmctco)*0.25)
) AS q_one_lower,
(
SELECT 576_VMC_Sol_Savings_Pct AS quartile_break
FROM orderedList
WHERE row_n = FLOOR((SELECT COUNT(*) FROM vmctco)*0.25) + 1
) AS q_one_upper
FROM orderedList
),
iqr AS (
SELECT
576_VMC_Sol_Savings_Pct,
(
(SELECT MAX(q_three_lower)
FROM quartile_breaks) +
(SELECT MAX(q_three_upper)
FROM quartile_breaks)
)/2 AS q_three,
(
(SELECT MAX(q_one_lower)
FROM quartile_breaks) +
(SELECT MAX(q_one_upper)
FROM quartile_breaks)
)/2 AS q_one,
1.5 * ((
(SELECT MAX(q_three_lower)
FROM quartile_breaks) +
(SELECT MAX(q_three_upper)
FROM quartile_breaks)
)/2 - (
(SELECT MAX(q_one_lower)
FROM quartile_breaks) +
(SELECT MAX(q_one_upper)
FROM quartile_breaks)
)/2) AS outlier_range
FROM quartile_breaks
)
SELECT MAX(q_one) OVER () - MAX(outlier_range) OVER () AS lower_limit,
MAX(q_three) OVER () + MAX(outlier_range) OVER () AS upper_limit
INTO #lowlim, #upplim
FROM iqr
LIMIT 1;
SELECT #lowlim, #upplim;

SOLVED: I went ahead and updated the version on the AWS instance to the same version as the NAS (8.0.28) and the query runs correctly now.

Related

wrong order in SQL using PDO

I have this query, which will be stored in a variable named $query (the actual query is much more complex, but this example successfully addresses my problem):
select * from
(
select
id_field as 'id',
date_field as 'date',
name_field as 'name',
cast((#counter := #counter + 1) AS SIGNED) as 'counter'
from my_table
cross join (select #counter := 0) as tmp
) as x
At some point, the final query will be:
$final_sql = "select * from ($query) t order by date desc"; //this can't be changed
What's happening is that I'm not getting the rows ordered by date, instead I'm getting some random order.
I've narrowed the problem to the double select * from while running the query with php/pdo on the server (localhost works fine). If I run the raw sql directly in database (localhost or server) it also works fine
If $query was like this, then I get the correct order (select * from removed):
select
id_field as 'id',
date_field as 'date',
name_field as 'name',
cast((#counter := #counter + 1) AS SIGNED) as 'counter'
from my_table
cross join (select #counter := 0) as tmp
But I've also noticed that if I keep the double select * from and get rid of the variables, then it will work as expected (but I need that column so it's not an option)
select * from
(
select
id_field as 'id',
date_field as 'date',
name_field as 'name'
from my_table
) as x
So, what is going on here?! How can I make it work on my server, just like my localhost?
localhost:
db > MySQL 8.0.25
php > 7.3.27
pdo > mysqlnd 5.0.12-dev - 20150407
server:
db > MariaDB 10.1.44
php > 7.3.17
pdo > mysqlnd 5.0.12-dev - 20150407
By nature the resultset of subquery are unsorted, while mysql keeps it mariadb skips it
What you can do is making a LIMIT with an ORDER BY so that mysql and mariadb keops the order you need
select * from
(
select
id_field as 'id',
date_field as 'date',
name_field as 'name',
cast((#counter := #counter + 1) AS SIGNED) as 'counter'
from my_table
cross join (select #counter := 0) as tmp
ORDER BY date_field
LIMIT 18446744073709551615
) as x

Implementing mariadb's NTILE() function in MYSQL 5.7

I can't use NTILE() because I'm currently on MYSQL 5.7 so I was wondering how would I go about converting this to be usable in 5.7 without NTILE.
Here's the query I'd like to convert:
SELECT
clientid,
ntile(4) over (
order by
last_order_date
) AS `rfm_recency`,
ntile(4) over (
order by
count_order
) AS `rfm_frequency`,
ntile(4) over (
order by
avg_amount
) AS `rfm_monetary`
FROM
(
SELECT
`clientid`,
MAX(`date`) AS `last_order_date`,
COUNT(`id`) AS `count_order`,
AVG(`price`) AS `avg_amount`
FROM
`design`
GROUP BY
`clientid`
) AS t
) AS p```

using row number in update query - MySQL

I have this DB2 query which I want to make MySQL compliant :
UPDATE
(
SELECT x.name, row_number() over () as rown from XYZ x where x.id = '123' and
x.div='abc')A
SET
A.name = 'name_1'
where
A.rown<= ( select count(*) -1 from XYZ where id='123' and div='abc');
Now, I tried writing this I MySQL:
UPDATE
(
select x.name, (#row_number := #row_number +1) as rown
from XYZ x, (Select #row_number := 0)as t
where x.id='123' and x.div='abc'
) A
Set
A.name = 'name_1'
where
A.rown<= ( select count(*) -1 from XYZ where id='123' and div='abc');
However, it gives me the error: The target table A of the UPDATE is not updatable
I have tried multiple ways but all in vain. Where am I going wrong?
Also if the DB2 query can be made into MySql in any other way, since Mysql doesn't support
row_number()
You can't update a derived table. You need to join with the real table so you can update it.
UPDATE XYZ AS x
JOIN (
select x.id, (#row_number := #row_number +1) as rown
from XYZ x, (Select #row_number := 0) as t
where x.id='123' and x.div='abc'
) AS A ON x.id = A.id
Set X.name = 'name_1'
where A.rown <= ( select count(*) from XYZ where id='123' and div='abc');
I'm not sure if this will do the same thing as the DB2 query, though. It seems to assume some inherent ordering in the table, and perhaps DB2 provides such a thing, but MySQL doesn't make any guarantees about ordering when you don't use ORDER BY. If you add ORDER BY x.id in the subquery, maybe that will do what you want.
In DB2 you can do it :
update XYZ f1
set f1.name='name_1'
where f1.id='123' and f1.div='abc'
and rrn(f1) not in
(
select max(rrn(f2)) from XYZ f2 where f2.id='123' and f2.div='abc'
)

Lost connection to MySQL server during query with UNION

i am getting error Lost connection to MySQL server during query with UNION query bellow.
select *
from `dealers`
where exists ((
select *
from `cars`
where `dealers`.`id` = `cars`.`dealer_id`
and exists (select *
from `dealers`
where `cars`.`dealer_id` = `dealers`.`id`)
and `dealer_id` = 27
order by `price` asc)
union (select *
from `cars`
where `dealers`.`id` = `cars`.`dealer_id`
and exists (select *
from `dealers`
where `cars`.`dealer_id` = `dealers`.`id`)
and `dealer_id` != 27
order by `price` desc))
order by `dealers`.`name` asc
Strange thing is that if i remove the last line entirely or if i sort by id instead of name it works fine.
Any ideas what could possibly be wrong with this?

SQL Version of CONCAT and LIMIT

Trying to follow Calendar Recurring/Repeating Events - Best Storage Method to design the database using SQL Server 2005.
When i run this below query
SELECT EV.*
FROM events EV
RIGHT JOIN events_meta EM1 ON EM1.event_id = EV.id
RIGHT JOIN events_meta EM2 ON EM2.meta_key = CONCAT( 'repeat_interval_', EM1.id )
WHERE EM1.meta_key = 'repeat_start'
AND (
( CASE ( 1299132000 - EM1.meta_value )
WHEN 0
THEN 1
ELSE ( 1299132000 - EM1.meta_value )
END
) / EM2.meta_value
) = 1
LIMIT 0 , 30
I am getting 'CONCAT' is not a recognized built-in function name.
I searched and seems like it is supported only in SQL Server 2012. How can i acheive this with SQL Server 2005/2008? Also what about LIMIT syntax in SQL Server?
I want the above sql version of query.
The SQL Server equivalent of limit is TOP. e.g
SELECT TOP 10 ID
FROM Table.
TOP is not really synomonous with LIMIT, because you can't pass 2 arguments to it, (e.g. LIMIT 10, 20) to specify the starting point. In SQL Server 2012 the equivalent is OFFSET FETCH, but in 2005 and 2008 versions you need to use ROW_NUMBER and filter on the value of this, e.g.
SELECT *
FROM ( SELECT *, RowNum = ROW_NUMBER() OVER(ORDER BY ID)
FROM T
) t
WHERE t.RowNumber BETWEEN 10 AND 30;
You can just use + to concatenate strings:
SELECT 'a' + 'b'
SQL Server 2012 introduces the CONCAT function
The equivalent function in SQL Server to CONCAT() is + and you can limit the resultset by using the TOP keyword.
Write your query as:
SELECT TOP 30 EV.*
FROM events EV
RIGHT JOIN events_meta EM1 ON EM1.event_id = EV.id
RIGHT JOIN events_meta EM2 ON EM2.meta_key = 'repeat_interval_' + CAST (EM1.id as varchar(10)) -- cast is required in case id column is int
WHERE EM1.meta_key = 'repeat_start'
AND (
( CASE ( 1299132000 - EM1.meta_value )
WHEN 0
THEN 1
ELSE ( 1299132000 - EM1.meta_value )
END
) / EM2.meta_value
) = 1
assumed that EM1.id is of type int you first have to convert it to a varchar.
To concatenate use the + operator. And use TOP instead of LIMIT in Sql-server.
This should work:
SELECT TOP 30 EV.*
FROM events EV
RIGHT JOIN events_meta EM1 ON EM1.event_id = EV.id
RIGHT JOIN events_meta EM2 ON EM2.meta_key = ('repeat_interval_' + CONVERT(nvarchar(max), EM1.id))
WHERE EM1.meta_key = 'repeat_start'
AND (
( CASE ( 1299132000 - EM1.meta_value )
WHEN 0
THEN 1
ELSE ( 1299132000 - EM1.meta_value )
END
) / EM2.meta_value
) = 1