SQL using IN when value stores in another ROW - mysql

So i have a few numbers that i stored into row as (1,2,3) ( lets name it as "ids" in table "some" )
And i using LEFT JOIN in another query to get some row using this field as ids
But when i wrote
LEFT JOIN sometable AS st WHERE some2.id IN some.ids
i get an error.
How i can use it correct, or maybe another way to realize that
thanks

Storing comma-delimited lists of integers as a string is the wrong way to store things. You should be using a junction table.
If you are stuck with this format and don't care about performance, you can use find_in_set():
where find_in_set(some2.id, some.ids) > 0

Related

MySQL Select from 1 Table, Insert into Another using Where across different databases

I have a select shown below that brings back the correct count per "sender_userid".
I want to insert this into a table in another database where there is a matching column "userid".
I'm not sure how to get the WHERE clause to work when used across database.
I've tried database.table.column but this appears wrong.
Is this possible? thx
WHERE statements must come before ORDER BY and GROUP BY statements. Also you should use the ON operator. Try this:
INSERT INTO dating_users.statistics (messages_sent)
SELECT COUNT(pid) FROM dating_messages.messages M
JOIN dating_users.statistics S
ON (S.userid = M.sender_userid)
GROUP BY sender_userid ORDER BY sender_userid ASC;
Edit: sorry I didn't realize that you were missing your actual JOIN statement. Just because you are INSERTing into a table doesn't make any data accessible from that table. You still need to JOIN to it.

Select records with same value of another (MySql)

I have a mysql table that has a column "my_set", a non-unique key, and another column "my_element", a unique key. Each my_sel value can correspond to multiple my_element values, whereas each my_element corresponds to only one my_set.
All values of theese two columns are integers unsigned (11).
Starting from a my_element value, in a single query and without nested selects, I need to find all other my_elements that has same my_set.
The solution I would think was nested select
select my_element
from table
where my_set = (
select my_set
from table
where my_element = <elementValue>
)
But, as I explained, I'd like to find a better, maybe faster way to do it without subselect, as performance is being an issue due to the huge number of similar queries in the db scheduled maintenance phase.
Also, better db structure advice could be appreciated, but currently db refactoring is not allowed.
I am not 100% sure what you are asking, but I will try to answer from what I understood.
I think you need to use self join to get all the elements related to given element( which are related by same my_set). Try the below query.
select t2.my_element
from table t1
join table t2 on t1.my_set = m2.my_set and t2.my_element <> t1.my_element
where t1.my_element = "element";
If it does not work. Create a sql fiddle with sample data, that would make it easy for us.
You can try the below query. If i understand it correctly, use the left outer join between two tables to get the ordered set of set and element.
select
mysetid,
myelementid
from
tableset a
left outer join
tableset b
on
a.setid = b.setid
order by
a.setid,b.elementid
Thanks.

WHERE IN with subquery NOT WORKING as expected

I am trying to get result from my categories table using the parent path i have created.
When i launch the request WHERE IN with manual data it's working perfectly.
When i am trying the same request dynamically with subquery, i got only one result instead of 4 expected.
I do not understand why, can you help me ?
http://sqlfiddle.com/#!2/88b68/6
/*Working query*/
SELECT t.id_categorie FROM t
WHERE t.id_categorie IN (1396,1399,1403,1412)
/*Not working by subquery ??*/
SELECT cat.id_categorie FROM t as cat
WHERE
cat.id_categorie IN (SELECT REPLACE(t.path,'.',',') FROM t WHERE t.id_categorie = 1412)
Thanks by advance,
Regards,
Using in with a comma delimited list does not do what you want. Even when you use a subquery. You could try this:
SELECT cat.id_categorie
FROM t cat
WHERE EXISTS (SELECT 1
FROM t
WHERE t.id_categorie = 1412 AND
find_in_set(cat.id_categorie, REPLACE(t.path, '.', ',')) > 0
);
I'm not sure what your data looks like or even what this query is supposed to be doing (it seems strange that the subquery is on the same table as the outer query). Usually, though, you want to store things in tables rather than delimited lists. You see, SQL has a built-in data structure for lists. It is called a table.
The reason this does not work is that your inner SELECT produces a single comma-separated VARCHAR, rather than four individual integers.
In MySQL you can use find_in_set, like this:
SELECT cat.id_categorie FROM t as cat
WHERE find_in_set(cat.id_categorie, (
SELECT REPLACE(t.path,'.',',')
FROM t WHERE t.id_categorie = 1412))
What I did was replacing the IN expression in your query with a call to find_in_set, leaving everything else the same.
Demo
However, this solution is fundamentally flawed, because it stores multiple values in a single column to represent a many-to-many relationship. A better approach to implementing this requirement is using a separate table that connects rows of the table to their related rows.

Query for multiple conditions in MySQL

I want to be able to query for multiple statements when I have a table that connects the id's from two other tables.
My three tables
destination:
id_destination, name_destination
keyword:
id_keyword, name_keyword
destination_keyword:
id_keyword, id_destination
Where the last one connects ids from the destination- and the keyword table, in order to associate destination with keywords.
A query to get the destination based on keyword would then look like
SELECT destination.name_destination FROM destination
NATURAL JOIN destination_keyword
NATURAL JOIN keyword
WHERE keyword.name_keyword like _keyword_
Is it possible to query for multiple keywords, let's say I wanted to get the destinations that matches all or some of the keywords in the list sunny, ocean, fishing and order by number of matches. How would I move forward? Should I restructure my tables? I am sort of new to SQL and would very much like some input.
Order your table joins starting with keyword and use a count on the number of time the destination is joined:
select
d.id_destination,
d.name_destination,
count(d.id_destination) as matches
from keyword k
join destination_keyword dk on dk.keyword = k.keyword
join destination d on d.id_destination = dk.id_destination
where name_keyword in ('sunny', 'ocean', 'fishing')
group by 1, 2
order by 3 desc
This query assumes that name_keyword values are single words like "sunny".
Using natural joins is not a good idea, because if the table structures change such that two naturally joined tables get altered to have columns the same name added, suddenly your query will stop working. Also by explicitly declaring the join condition, readers of your code will immediately understand how the tables are jones, and can modify it to add non-key conditions as required.
Requiring that only key columns share the same name is also restrictive, because it requires unnatural column names like "name_keyword" instead of simply "name" - the suffix "_keyword" is redundant and adds no value and exists only because your have to have it because you are using natural joins.
Natural joins save hardly any typing (and often cause more typing over all) and impose limitations on join types and names and are brittle.
They are to be avoided.
You can try something like the following:
SELECT dest.name_destination, count(*) FROM destination dest, destination_keyword dest_key, keyword key
WHERE key.id_keyword = dest_key.id_keyword
AND dest_key.id_destination = dest.id_destination
AND key.name_keyword IN ('sunny', 'ocean', 'fishing')
GROUP BY dest.name_destination
ORDER BY count(*), dest.name_destination
Haven't tested it, but if it is not correct it should show you the way to accomplish it.
You can do multiple LIKE statements:
Column LIKE 'value1' OR Column LIKE 'value2' OR ...
Or you could do a regular expression match:
Column LIKE 'something|somtthing|whatever'
The trick to ordering by number of matches has to do with understanding the GROUP BY clause and the ORDER BY clause. You either want one count for everything, or you want one count per something. So for the first case you just use the COUNT function by itself. In the second case you use the GROUP BY clause to "group" somethings/categories that you want counted. ORDER BY should be pretty straight forward.
I think based on the information you have provided your table structure is fine.
Hope this helps.
DISCLAIMER: My syntax isn't accurate.

string search in MySQL Query

My MySQL field having skills field(string) like,
1)php,mysql
2)java
3)java,c
I need to select the column with skills field condition. Condition may be Like,
skills="php" // o/p => 1st column
or
skills = "mysql,c" // o/p => 1st and 3rd column
How I can write Query.? Here im using PHP.
One way to do it
SELECT *
FROM table1
WHERE skills LIKE '%mysql%'
OR skills LIKE '%c%'
SQLFiddle
It would be much easier if you'd normalized your data
Use a procedure like this one:
Split comma separated values from one column to 2 rows in the results. MySQL
To split your csv skills field into a temp table with rows for each skill
Then do the same thing with your search parameters (which I assume is also csv string passed in)
Then simply apply a JOIN over the two results and get the DISTICT Id.
there are many solutions for splitting a comma separated string in MySQL (though it's not particularly good at this task)... if you can't properly normalize the data then you can't very well complain about inefficient query routines.