Multiple JOINs too complex - mysql

This has become more complex than I can follow. I have modified this query from another post here and now I need to add another join, but it's not working.
Here is the current query in MySQL:
SELECT * FROM (SELECT *,
#rn := IF(#prev = class, #rn + 1, 1) AS rn,
#prev := class
FROM HeatWaveData
JOIN
(SELECT #prev := NULL, #rn := 0) AS vars
ORDER BY class, score DESC)
AS T1
WHERE rn <= 3
AND score > 0
AND dsqreason = ''
AND class <> ''
Now I need to JOIN (SELECT * FROM Awards WHERE active ON Awards.award = HeatWaveData.award)
but it fails with errors. I've tried several changes and different things but keep getting errors.
Here is my updated query and error:
SELECT * FROM (SELECT *,
#rn := IF(#prev = class, #rn + 1, 1) AS rn,
#prev := class
FROM HeatWaveData
JOIN
(SELECT #prev := NULL, #rn := 0) AS vars
ORDER BY class, score DESC)
AS T1
LEFT JOIN
(SELECT * FROM Awards WHERE active = '1'
ON Awards.award = T1.award) AS T2
WHERE rn <= 3
AND score > 0
AND dsqreason = ''
AND class <> ''
Error:
error: #1064 - You have an error in your SQL syntax; check the manual that
corresponds to your MySQL server version for the right syntax to use near
'ON Awards.award = T1.award) AS T2 WHERE rn <= 3 AN' at line 11

Just try to replace your sub-select with a "normal" join:
old:
LEFT JOIN
(SELECT * FROM Awards WHERE active = '1'
ON Awards.award = T1.award) AS T2
new:
LEFT JOIN Awards AS T2
ON T2.award = T1.award AND T2.active = '1'

Related

Update field in a table with values from another field from another table

I need to update the last 110 values ​​of the descricao_geral table with the last 110 values ​​of the relevo table
I'm doing this:
UPDATE descricao_geral
SET id_relevo_fk = (SELECT id_relevo FROM relevo ORDER BY id_relevo DESC LIMIT 110)
ORDER BY id_descricao DESC
LIMIT 110
The error I've received:
Subquery returns more than 1 row
This is really tricky. You need to join the tables together, but you don't have an appropriate key.
You can use variables to assign a sequential value and then use this for the join:
update descricao_geral g join
(select (#rng := #rng + 1) as rn, g2.id_descricao
from (select g2.* from descricao_geral g2 order by g2.id_descricao desc) g2 cross join
(select #rng := 0) params
limit 110
) g2
on g.id_descricao = g2.id_descricao join
(select (#rnr := #rnr + 1) as rn, r.id_relevo
from (select r.* from relevo r order by r.id_relevo desc) r cross join
(select #rnr := 0) params
) r
on g2.rn = r.rn
set g.id_relevo_fk = r.id_relevo;

How to write a MySQL query to generate a new table by selecting some values from it?

I have a table named orthologygen:
ko, gene
ko:1, has:1
ko:2, has:2
ko:3, has:3
ko:4, pps:4
ko:4, pps:5
ko:3, rno:3
ko:3, rno:4
ko:2, rno:6
ko:4, rno:7
and I want to generate a new table using MySQL like this:
has,rno
has:1, rno:3
has:2, rno:4
has:3, rno:6
My current version of this query is like this:
select t1.hsa, t2.rno
from
(SELECT #n := #n + 1 as id, o1.gene as hsa FROM orthologygen o1, (select #n := 0) m where gene like "hsa%") t1
join
(SELECT #n := #n + 1 as id, o2.gene as rno FROM orthologygen o2, (select #n := 0) m where gene like "rno%") t2
on t1.id = t2.id
However, it returns empty, do you know how to fix this? Thanks
Oh, I see. You need different variables and to initialize them:
select h.hsa, r.rno
from (select (#nh := #nh + 1) as id, o1.gene as hsa
from orthologygen o1 cross join
(select #nh := 0) m
where gene like 'hsa%'
) h join
(select (#nr := #nr + 1) as id, o2.gene as rno
from orthologygen o2 cross join
(select #nr := 0) m
where gene like 'rno%'
) r
on r.id = h.id

Get row position in the result?

How use #row_number like position row in result in this SQL:
SELECT s.*,
s2.priority AS `priority`,
#row_number := #row_number := #row_number + 1 AS `top`
FROM (SELECT #row_number := 0) init, `server` s
LEFT JOIN servers_services ss ON (s.id = ss.server_id)
LEFT JOIN service s2 ON (s2.id = ss.service_id)
WHERE s.is_banned = 0
ORDER BY ss.service_id IS NULL, priority DESC
#row_number takes values {1, 12, 89 ...} Why?
I don't have experience with variables in MySQL, so my anser can be wrong.
My guess is: You cross join row numbers with your tables. Then in the WHERE clause you dismiss records, so you are left with only some of the original row numbers.
As to how to solve this, I imagine not to join the undesired records in the first place should help:
FROM (SELECT #row_number := 0) init
JOIN server s ON s.is_banned = 0
LEFT JOIN servers_services ss ON (s.id = ss.server_id)
LEFT JOIN service s2 ON (s2.id = ss.service_id)

mysql perform same calculation for all rows on another table

I have my query determined:
SELECT *
FROM `participation`
LEFT JOIN parties ON parties.id = participation.party_id
WHERE `riding_id` = 10001
AND `election_id` = 41
ORDER BY num_votes DESC
LIMIT 1
This accurately produces the result I want.
The result is the most voted for party.
Now I want to perform this same query on every row of a TABLE ridings
which contains all the riding_id rows. Having some trouble getting it.
I don't want to join the other table - but go through every row and perform the same calculation as above - on each row.
Something like:
SELECT *
FROM `participation`
LEFT JOIN parties ON parties.id = participation.party_id
WHERE `riding_id` = "LOOP ALL riding_id IN ridings TABLE"
AND `election_id` = 41
ORDER BY num_votes DESC
LIMIT 1
Any help would be appreciated.
It is tempting to just use a subquery:
SELECT *
FROM participation LEFT JOIN
parties
ON parties.id = participation.party_id
WHERE riding_id IN (SELECT riding_id FROM ridings) AND
election_id = 41
ORDER BY num_votes DESC
But, you no longer get the top vote getter. You get everything.
Here is a method using variables to get just the top vote getting for each riding_id:
SELECT *
FROM (SELECT *,
(#rn := if(#r = riding_id, #rn + 1,
if(#rn := riding_id, 1, 1)
)
) as seqnum
FROM participation LEFT JOIN
parties
ON parties.id = participation.party_id CROSS JOIN
(SELECT #rn := 0, #r := -1) params
WHERE riding_id IN (SELECT riding_id FROM ridings) AND
election_id = 41
ORDER BY riding_id, num_votes DESC
) pp
WHERE seqnum = 1;

Subquery with order by

I wrote a query with a subquery and both of them have an order by.
I have a weird behavior, sometimes I don't get back all the rows, sometimes I have 0 rows, but if I run the inner query I have the correct rows always. Is there some limitation about subquery? MySql is version 5.5
thanks a lot
SELECT
*
FROM
(
SELECT
#fakeId := #fakeId + 1 AS fakeId,
#balance := (#balance + traIn.amount) AS balance,
FROM
(SELECT #fakeId := 0, #balance := 0) AS vars,
table1 traIn
INNER JOIN table2 traTypeIn ON traIn._id = traTypeIn.id
INNER JOIN table3 ptfIn ON traIn.ptf_id = ptfIn.id
LEFT JOIN `user` u ON u.id = traIn.user_create_id
LEFT JOIN `user` up ON up.id = traIn.user_update_id
WHERE
<--- a couple of constraints -->
ORDER BY
traIn.date
) AS data
ORDER BY data.fakeId DESC
LIMIT 50;
Why do you don't, on your sub-query, select traIn.date, and after that, select only fakeId, balance
Somethings like that :
SELECT
data.fakeId, data.balance
FROM
(
SELECT
#fakeId := #fakeId + 1 AS fakeId,
#balance := (#balance + traIn.amount) AS balance,
traIn.date as date1
FROM
(SELECT #fakeId := 0, #balance := 0) AS vars,
table1 traIn
INNER JOIN table2 traTypeIn ON traIn._id = traTypeIn.id
INNER JOIN table3 ptfIn ON traIn.ptf_id = ptfIn.id
LEFT JOIN `user` u ON u.id = traIn.user_create_id
LEFT JOIN `user` up ON up.id = traIn.user_update_id
WHERE
<--- a couple of constraints -->
) AS data
ORDER BY data.date1, data.fakeId DESC
LIMIT 50;