MySql Select 2 tables Like - mysql

I have this query but apparently it can loop and crash the server.
SELECT neveras.Panel, contactos.Email FROM neveras, contactos
WHERE neveras.Alarma = 1 And Estado <> 1
And contactos.Sensor
LIKE CONCAT('%,',(Select Usuario FROM neveras where Alarma = 1),',%')
Table neveras:
Id|Panel|Usuario|Alarma|Estado
1 uno 1 1 2
2 dos 1 2 1
3 tres 2 2 1
4 cuatro 2 2 1
5 cinco 3 2 1
Table Contactos:
Id |Email |Nombre |Sensor
1 uno#uno nombre1 1,3,5
2 dos#dos nombre2 2,4
This table has this structure to avoid repeating values
I appreciate your help.

This is a bit of a guess as I am not 100% sure what you are trying to achieve, but give this a try -
SELECT neveras.Panel, contactos.Email
FROM neveras
INNER JOIN contactos
ON FIND_IN_SET(neveras.Usuario, contactos.Sensor)
WHERE neveras.Alarma = 1
AND neveras.Estado <> 1
As Mosty pointed out it would definitely help if you posted an example of what you expect in the result.
Further to that, you should move the multiple values in your Sensor field to a many-to-many table (contactos_id, sensor_id). There is no way for the optimizer to do anything clever with your comma sparated list so any filtering or joining on that field will be very inefficient.

Related

How to join 2 rows in database?

I got some issues while structuring my database and I would like to know how to solve the below question .
I have a table in database :
id
id_study
writer
1
1
writer1
2
1
writer2
3
2
writer3
Please help me how to combine above 2 table rows to produce output like below :
id
id_study
writer
1,2
1
writer1, writer2
3
2
writer3
SELECT GROUP_CONCAT(id) as id, id_study,GROUP_CONCAT(Writer) as Writer
FROM TABLE
GROUP BY id_study;

Limit selected results by unique selected IDs when using left joins

I have a table users and some other tables like images and products
Table users:
user_id user_name
1 andrew
2 lutz
3 sophie
4 michael
5 peter
6 oscor
7 anton
8 billy
9 henry
10 jon
Tables images:
user_id img_type img_url
1 0 url1
1 1 url4
2 0 url5
7 0 url7
8 0 url8
9 1 url9
Table Products
user_id prod_id
1 5
1 55
2 555
8 5555
9 5
9 55
I use this kind of SELECT:
SELECT * FROM
(SELECT user.user_id,user.user_name, img.img_type, prod.prod_id FROM
users
LEFT JOIN images img ON img.user_id = users.user_id
LEFT JOIN products prod ON prod.user_id = users.user_id
WHERE user.user_id <= 5) AS users
ORDER BY user.user_id ASC
The result should be the following output. Due to performance improvements, I use ORDER BY and an inner select. If I put a LIMIT 5 within the inner or outer select, things won't work. MySQL will hard LIMIT the results to 5. However I need the LIMIT of 5 (pagination) found unique user_id results which would lead to 9 in this case.
Can I use maybe an if-statement to push an array with found user_id and break/finish up the select when the array consist of 5 UIDs? Or can I modify somehow the select?
user_id user_name img_type prod_id
1 andrew 0 5
1 andrew 1 5
1 andrew 0 55
1 andrew 1 55
2 lutz 0 5
2 lutz 0 55
3 sophie null null
4 michael null null
5 peter null null
results: 9
LIMIT 5 and user_id <= 5 do not necessarily give you the same results. One reason: There are multiple rows (after the JOINs) for user_id = 1. This is because there can be multiple images and/or multiple products for a given 'user'.
So, first decide which you want.
LIMIT without ORDER BY gives you an arbitrary set of rows. (Yeah, it is somewhat predictable, but you should not depend on it.)
ORDER BY + LIMIT usually implies gathering all the potentially relevant rows, sorting them, then doing the "limit". There are sometimes ways around this sluggishness.
LEFT leads to the NULLs you got; did you want that?
What do you want pagination to do if you are displaying 5 items per page, but user 1 has 6 images? You need to think about this edge case before we can help you with a solution. Maybe you want all of user 1 on a page, even if it exceeds 5? Maybe you want to break in the middle of '1'; but then we need an unambiguous way to know where to continue from for the next page.
Probably any viable solution will not use nested SELECTs. As you are finding out, it leads to "errors". Think of it this way: First find all the rows you need to display on all the pages, then carve out 5 for the current page.
Here are some more musings on pagination: http://mysql.rjweb.org/doc.php/pagination

query the same field multiple times in the same query

I need to filter a table in mysql but can't get past the beginning.
The table has 2 fields:
ID_house house_feature
1 1
1 2
1 4
1 5
2 1
2 3
2 4
3 1
3 2
3 3
I need to filter this table using the following parameters:
house feature = 1
AND
house feature = 2
AND
house feature = 3
So that I get all houses with the requested feature.
I already tried to create something similar to this:
SELECT *
FROM houses
WHERE
house_feature = 1
AND
house_feature = 2
AND
house_feature = 3
But it doesn't work as I expected.
Is there a way to get this result with MySQL?
It seems that I acn filter the table using only the OR operator but this way I can't get the right result.
Thanks in advance for any help.
tony
You can do so ,by matching the distinct count of features per house ,so the house with exactly these 3 features will be returned
SELECT *
FROM t
WHERE
house_feature IN(1 ,2,3)
group by ID_house
having count(distinct house_feature) = 3
Demo

MYSQL Can WHERE IN default to ALL if no rows returned

Have a existing table of results like this;
race_id race_num racer_id place
1 0 32 2
1 1 32 3
1 2 32 1
1 3 32 6
1 0 44 2
1 1 44 2
1 2 44 2
1 3 44 2
etc...
Have lots of PHP scripts that access this table output the results in a nice format.
Now I have a case where I need to output the results for only certain race_nums.
So I have created this table races_included.
race_view race_id race_num
Day 1 1 0
Day 1 1 1
Day 2 1 2
Day 2 1 3
And can use this query to get the right results.
SELECT racer_id, place from results WHERE race_id=1
AND race_num IN
(SELECT race_num FROM races_included WHERE race_id='1' AND race_view='Day 1')
This is great but I only need this feature for a few races and to have it work in a compatible mode for the simple case show all races. I need to add alot of rows to the races_included table. Like
race_view race_id race_num
All 1 0
All 1 1
All 1 2
All 1 3
95% of my races don't use the daily feature.
So I am looking for a way to change the query so that if for race 1 there are no records in the races_included table it defaults to all races. In addition I need it to be close the same execution speed as the query without the IN clause, because this query Or variations of it are used a lot.
One way that does work is to redefine the table as races_excluded and use NOT IN. This works great but is a pain to manage the table when races are added or deleted.
Is there a simple way to use EXISTS and IN in tandem as a subquery to get the desired results? Or some other neat trick I am missing.
To clarify I have found a working but very slow solution.
SELECT * FROM race_results WHERE race_id=1
AND FIND_IN_SET(race_num, (SELECT IF((SELECT Count(*) FROM races_excluded
WHERE rid=1>0),(SELECT GROUP_CONCAT(rnum) FROM races_excluded
WHERE rid=1 AND race_view='Day 1' GROUP BY rid),race_num)))
It basically checks if any records exists for that race_id and if not return a set equal to the current race_num and if yes returns a list of included race nums.
You can do this by using or in the subquery:
SELECT racer_id, plac
from results
WHERE race_id = 1 AND
race_num IN (SELECT race_num
FROM races_included
WHERE race_id = '1' AND (race_view = 'Day 1' or raw_view = 'ANY')
);

MySql - order a query result in "some mode"

I have this data on a table :
id name field
0 marco attack
1 andrea defense
2 luca medium
3 ernesto defense
4 vittorio medium
5 manuele attack
i need to order as field. BUT, the priority list order (for my example) should be defense-medium-attack.
so it must return :
andrea, ernesto, luca, vittorio, marco, manuele.
How can do it? bye
You should store the fields in a separate table and give them a sort order. Then you can join to that table.
As well as allowing you to sort efficiently, it also makes the table structure more relational - which is good.
id field sort
1 defense 1
2 medium 2
3 attack 3
id name field
0 marco 3
1 andrea 1
2 luca 2
3 ernesto 1
4 vittorio 2
5 manuele 3
select p.name,
ps.field
from players p
join playersort ps
on p.field = ps.id
order by ps.sort
SELECT
X.id,
X.name,
X.field
FROM (
SELECT id,
name,
field,
CASE field WHEN 'defense' THEN 1
WHEN 'medium' THEN 2
WHEN 'attack' THEN 3
END AS SortValue
FROM MyTable) AS X
ORDER BY X.SortValue