I have this following query
SELECT *
FROM tablea,
tableb
WHERE tablea.a = tableb.b
AND partner_id = 1
okay, this works fine, but I want SELECT from multiple columns, for example:
SELECT *
FROM tablea,
tableb
WHERE tablea.a = tableb.b OR tableb.c OR tableb.d OR tableb.e OR...
AND partner_id = 1
but this return with zero
ohh, it's look like funny, but what's the problem?
thank you for your help!
Your current statement is being parsed as:
WHERE (tablea.a = tableb.b) OR (tableb.c) OR (tableb.d) OR (tableb.e) OR...
You must either explicitly compare against tablea.a in each clause or else use MySQL's IN() operator:
WHERE tablea.a IN (tableb.b, tableb.c, tableb.d, tableb.e, ...)
Related
I am trying to write a query that can match a list of strings on a subquery.
Example
TableA
id
value
1
somevalue1
2
somevalue2
TableB
id
value
tableA_id
1
test1
1
2
test2
1
3
test1
2
I need a query that returns all the entries from TableA who have an entry in TableB for a list of strings.
For:
select * from TableA ta where ('test1', 'test2') = (select tb.value from TableB tb where tb.tableA_id = ta.id);
Expected result would be
id
value
1
somevalue1
because this is the only entry in TableA that has entries for both those string values in TableB.
I tried to look on the internet on how to match a list of string in MySQL but didn't found something that I can use, my sql skills are at beginner level.
Thanks in advance.
Actually you may not even need to involve TableA in this query. I suggest the following canonical aggregation approach on TableB:
SELECT tableA_id
FROM TableB
WHERE value IN ('test1', 'test2')
GROUP BY tableA_id
HAVING COUNT(DISTINCT value) = 2;
So I need to do a query based on the results of another query. Is there a way for me to set the result of a query to a variable so I can use the result of that in another query?
Example:
{original query} --->
SELECT
tablea.number
FROM tablea
INNER JOIN tableb
ON tablea.name = tableb.name
WHERE tableb.zip = '11111'
Now I want to use this result to then do another query:
SELECT *
FROM tablea
WHERE number = (results of last query)
I think theres a way to set the first query to a variable so that that way the second one can just use the result, just not sure how. Thanks.
You can use IN or EXISTS:
SELECT *
FROM tablea
WHERE name IN (SELECT name FROM tableb WHERE zip = '11111')
Or
SELECT *
FROM tablea A
WHERE EXISTS (SELECT 1 FROM tableb
WHERE zip = '11111'
AND name = A.name)
You can select directly into a variable:
declare #number int
select #number = tablea.number
from ...etc...
select *
from tablea
where number = #number
There are a few other ways of doing the same thing, but this is how you'd do it with a variable.
In the 2 queries below the result set would be the same, but I was wondering if there would be any difference in speed because of the order of the comparison arguments in the ON clauses.
In the first query it matches table1.c1 = table2.c1, and the second the other way around.
SELECT * FROM table1 JOIN table2 ON (table1.c1 = table2.c1)
Or
SELECT * FROM table1 JOIN table2 ON (table2.c1 = table1.c1)
The two queries are strictly the same, there is no difference between them.
It just a convention to use the first form:
SELECT * FROM table1 JOIN table2 ON (table1.c1 = table2.c1)
Ever since the boolean expression inside ON clause returns TRUE, a record will be send to the result set output. If one of the tables returns 0 record, even if the ON clause returns TRUE, result set will be empty. So there is no difference that how you'd like to write a boolean expression inside the ON clause. Like this which means Cross Join!
Cheers
Select *
From dbo.Person As A
Inner Join
dbo.PersonOrder As B
On 1 = 1
Is there a way to write a single query to check if a set of rows matches a set of values? I have one row per set of values that I need to match and I'd like to know if all rows are matched or not. I could perform this via multiple queries such as:
select * from tableName where (value1, value2) = ('someValue1', 'someValue2')
select * from tableName where (value1, value2) = ('someOtherValue1', 'someOtherValue2')
...and so on, up to an arbitrary number of queries. How could this sort of thing be re-written as a single query where the query returns ONLY if all values are matched?
You could try something like:
select t.*
from tableName t
join (select 'someValue1' value1, 'someValue2' value2 union all
select 'someOtherValue1', 'someOtherValue2') v
on t.value1 = v.value1 and t.value2 = v.value2
where 2=
(select count(distinct concat(v1.value1, v1.value2))
from (select 'someValue1' value1, 'someValue2' value2 union all
select 'someOtherValue1', 'someOtherValue2') v1
join tableName t1
on t1.value1 = v1.value1 and t1.value2 = v1.value2)
If you have a large number of value pairs that you want to check, it may be easier to insert them into a temporary table and use the temporary table in the above query, instead of two separate hard-coded virtual tables.
What about:
SELECT *
FROM tableName
WHERE value1 IN ('someValue1', 'someOtherValue1') AND
value2 IN ('someValue2', 'someOtherValue2')
Match if exactly two records found
Select students who got q13 wrong and Q14 right
SELECT qa.StudentID FROM questionAnswer qa, Student s
WHERE qa.StudentID=s.StudentID AND
((QuestionID=13 AND Pass=0) OR (QuestionID=14 AND Pass=1))
GROUP BY qa.StudentID
HAVING COUNT(*)=2;
The Where clause matches any records where q14 is correct and q13 is incorrect
We then group by the StudentID
The having requires there to be two records
if select * from table where x=1 returns 0 rows, then I need select * from table where x=2 [or some other query]. Is it possible to do this in a single MySQL query with a conditional statement?
Edit: All answers with UNION work, but only if both queries select from the same table (or tables with the same number of columns). What if the second query is applied on a different table with joins?
Let me write down the my queries to make the question more clear:
1st:
SELECT table1.a, table2.b from table1 LEFT JOIN table2 ON table2.x= table1.x
WHERE .....
if the result from the 1st one is null then:
2nd:
SELECT table1.a FROM table1
WHERE ....
I will be using the rows from the 1st query if it returns any, otherwise the 2nd one will be used.
This appears to work from a quick test I just did and avoids the need to check for the existence of x=1 twice.
SELECT SQL_CALC_FOUND_ROWS *
FROM mytable
WHERE x = 1
UNION ALL
SELECT *
FROM mytable
WHERE
FOUND_ROWS() = 0 AND x = 2;
Edit: Following your clarification to the question obviously the 2 queries will need to be UNION compatible for the above to work.
The answer to your updated question is No. This is not possible in a single query. You would need to use some conditional procedural logic to execute the desired query.
You could try...
SELECT *
FROM mytable
WHERE x = 1
UNION
SELECT *
FROM mytable
WHERE x = 2 AND
NOT EXISTS (SELECT *
FROM mytable
WHERE x = 1);
if you don't consider it too ghastly a hack.
yes
Subqueries with EXISTS or NOT EXISTS
http://dev.mysql.com/doc/refman/5.1/en/exists-and-not-exists-subqueries.html
example :
SELECT column1 FROM t1 WHERE NOT EXISTS (SELECT * FROM t2);
If the two queries return different number of columns, you can pad one of the results with empty columns and also add an identifier column first.
SELECT SQL_CALC_FOUND_ROWS 1 query_type, mytable.*,
'' col1, '' col2, '' col3, '' col4
FROM mytable
WHERE x = 1
UNION ALL
SELECT 2, mytable2.*
FROM mytable2
WHERE
FOUND_ROWS() = 0 AND x = 2;
Where mytable2 has 4 more columns than mytable.
The simplest explanation is that:
SELECT IF(1 = 2,'true','false'); --> false
SELECT IF(1 = 1,' true','false'); --> true
SELECT IF(1 = 2,' true','false'), IF(1 = 1,' true','false'); --> false | true
The 'if' statement give some functionality to selected values.
The structure is something like this:
SELECT IF(<your statement>), ...<selected params>... FROM <your tables>
A great explanation can be found here.
SQL_CALC_FOUND_ROWS and FOUND_ROWS cannot be used in a single query, even if separate by UNION statements.
The correct way to do this would be:
WITH my_cte AS
(
SELECT * from original_set
)
SELECT * FROM my_cte
UNION ALL
SELECT opt.* FROM optional_set opt JOIN (SELECT count(*) v FROM my_cte) count ON count.v=0;
With the JOIN and the UNION ALL the performance of this query is almost equivalent to either of the individual standalone queries
you can use EXIST and NOT EXIST statement to check that result is null or not. if result is Null then you can get value from table2.