I have a code like this:
SELECT *
FROM table1
WHERE integer NOT IN (
SELECT varchars FROM table2 WHERE id = 1)
varchars consists of numbers separated by comma (1, 2, 3, 4 etc.) This code doesn't work correctly because the SELECT part between brackets gets enclosed by quotes ' ' and MySQL only reads the first integer before the first comma. How do I get read of those quotes or make that code work?
SELECT *
FROM table1
WHERE integer NOT IN (
SELECT varchars FROM table2 WHERE id = 1 FIELDS ENCLOSED BY 'NULL')
didn't help me either since it causes error #1064.
SELECT * FROM table1 LEFT JOIN table 2 ON FIND_IN_SET(integer,varchars) AND id =1 WHERE varchars IS NULL
This one is a correct answer mentioned by Mihai in the comment section above. Version of Sebas also works but when varchars for id = 1 in table2 doesnt exist it returns NULL while it should return all integer from table1 instead.
SELECT *
FROM table1 CROSS JOIN (SELECT varchars FROM table2 WHERE id = 1) AS t
WHERE NOT FIND_IN_SET(integer, t.varchars)
;
CROSS JOIN so the query is just executed on its own (as long as it returns a record)
FIND_IN_SET searches into a comma separated list of values.
Related
I need to use selected rows in another query without selecting them again as subquery. Would be perfect if here possible to store them as variable.
What I mean:
/* First query: only one column returns (always), but multiple records, trying to store them as string */
SET #result := (SELECT GROUP_CONCAT(target_field SEPARATOR ',')
FROM table_one
WHERE condition;
/* Second query: need to pass saved array into IN() condition */
SELECT *
FROM table_two
WHERE id IN(#result);
But suddenly it won't work because #result processed as one string value, not as array.
Is it possible to pass variable as array? Any alternative solution (except subqueries) allowed.
You can use the function FIND_IN_SET():
SELECT *
FROM table_two
WHERE FIND_IN_SET(id, #result);
you could just use a subquery in your where condition. This should be ok for mySql
SELECT *
FROM table_two
WHERE id IN(SELECT id from table_one where condition_one);
JOIN between tables can be used in this case:
SELECT *
FROM table_two
JOIN table_one ON table_two.id = table_one.target_field
WHERE table_one condition;
I get data from MySQL with if statement as code below. but I get an error:
Error Code: 1241. Operand should contain 1 column(s).
so can someone can help me?
I can not put it into the procedure, because I am using spring + mybatis in the project and i will put this code into them.
SELECT IF((SELECT COUNT(*) FROM table1 WHERE someField = 'A') < 0,
(SELECT * FROM table2 WHERE someField = 'A'),
(SELECT * FROM table1 WHERE someField = 'A'))
From the comments: I wanna get data of 1 in 2 tables when table 1 don't have data I will get data from table 2.
That sounds like union all and not exists:
select * from table1 where someField = 'A'
union all
select * from table2 where not exists(select 1 from tabe1 where someField = 'A'
Note that, for this to work, both tables must contain exactly the same number of columns, whith aligned datatypes. You should really be enumerating the columns that you want to show in the resultset in both unioned queries, to avoid any possible ambiguity. If needed, you can cast columns or add litteral values to any or both of the resultset to align the resultsets (without seeing your actual data structures, I cannot tell how to do).
I have a table field named category_ids (text) which saves another table's ids as "1,2,3".
Now i want to use this category_ids to a sql IN() query. the query will be like tab1.category_id IN (select category_ids from tab2). but i'm facing issue as select category_ids from tab2 returns '1,2,3' so IN() query not working.
Is there any simple way to convert '1,2,3' to ('1','2','3') or (1,2,3) in sql?
You may use FIND_IN_SET here:
SELECT *
FROM tab1
WHERE FIND_IN_SET(tab1.category_id,
(select category_ids from tab2));
This is just a sample query, your actual one may differ. But the point is that if you want to search for '1' inside a CSV string '1,2,3', then there is a way to do it.
As others have already mentioned, you should avoid storing CSV data in your tables. When I see FIND_IN_SET being heavily used there is usually a smell.
try
tab1.category_id IN (select REPLACE(category_ids, '''', '') from tab2)
If table2 has more than one row, you can use exists with find_in_set():
select t1.*
from table1 t1
where exists (select 1
from table2 t2
where find_in_set(t1.category_id, t2.category_ids) > 0
);
Note that this is a very poor data structure. You should have a single row for each category id in table2. If you did, then the query would be simpler and have better performance.
I have two SQL tables, call them t1 and t2. Both have column names str_id. The str_id is typically a 10 digit string, but I have special str_ids that begin with 'sp' followed by a normal 10 digit str_id. I would like to select all the 'sp' str_ids from t1, remove the sp, and look up the str_id in t2. I tried this query:
Select
str_id,
desired_column
From
t2
Where
str_id in (
Select
substr(str_id, 3)
From
t1
Where
str_id Like 'sp%' and
other_column = 'my_value'
);
Syntactically, this command seems correct, but when I run it my SQL frontend just hangs. If I run the command without the SUBSTR, then it executes fine, but it doesn't return the results I want because all the str_ids have sp prefixed. Just for reference, the command that works is:
Select
str_id,
desired_column
From
t2
Where
str_id In (
Select
str_id
From
t1
Where
str_id Like 'sp%' and
other_column = 'my_value'
);
What can I do to fix the query above?
Show the EXPLAIN outputs of those two, but I assume with the normal one mysql is able to directy crossreference indexes, while the SUBSTR one requires creating an intermediate resultset, and checking each individual item from t2. Which is a nice example why prefixing values with significant data is about as bad as people storing delimited strings in 1 column: hard to work with.
So, you're saying that t2.str_id values do not contain the 'sp' prefix, while t1.str_id do? You may want to rethink your data model. I suspect that there is an index on t1.str_id that cannot be used when you are trying to match subst(t1.str_id,3) to t2.str_id.
Depending on the relative sizes of the tables, this may perform faster:
SELECT
str_id, desired_column
FROM
t2
WHERE
concat( 'sp' , str_id ) IN (
SELECT str_id FROM t1
WHERE str_id LIKE 'sp%' and other_column = 'my_value'
);
Edited my answer. Try running this instead
SELECT str_id,
(
SELECT desired_column
FROM t2
WHERE str_id = SUBSTR(t1.str_id, 3)
)
FROM t1
WHERE str_id LIKE 'sp%' AND other_column = 'my_value'
I have the following query working:
SELECT DISTINCT table1.field1, table1.field2
FROM table1
WHERE table1.field3 IN (1,2,3)
Result:
field1 field2
Data1 60
Data2 61
Data3 62
And the following query only gives me the first row when it should give the exact same result as the first query.
SELECT DISTINCT table1.field1, table1.field2
FROM table1
WHERE table1.field3 IN (SELECT table2.field1 FROM table2 WHERE table2.field2 = 100)
Result:
field1 field2
Data1 60
If I execute the subquery (SELECT table2.field1 FROM table2 WHERE table2.field2 = 100), the result is "1,2,3", exactly like the first query.
What i'm I missing?
What you're missing is that a string with the value '1,2,3' is not a list of three integers. It's one string.
If you want x IN (SELECT y FROM z) to behave in the same way as x IN (1,2,3), then your sub-query must return three items, with the values 1, 2, and 3.
There are Split() functions on the web that take a string and return a record set consisting of multiple integers. And that may fix your problem.
But the fact that you have a single record with a single field holding multiple values is a sign of a deeper problem. You should never store multiple values in a relational database as a single string. Instead store multiple records, or multiple fields.