I have three tables. t1,t2,t3. I want to get the common values between t2,t3 and select the whole record from t1. When I type my statement as in:
select * from db.t1 where col1
IN (
select col1 from t2 , t3
where t2.col1=t3.col1);
I get a syntax error. What is wrong ?
Assuming you're testing that t2.col1=t3.col1 (instead of col1.t2=col1.t3, as shown), then one other problem is the ambiguity for col1 in the inner SELECT.
This:
where col1.t2=col1.t3);
Should be:
where t2.col1=t3.col1);
I'm not sure, but maybe you have to rename your encapsulated col1 :
select * from db.t1 where t1.col1
IN (
select col1 as col1bis from t2 , t3
where t2.col1 = t3.col1);
Related
I found a strange bug (I guess) in mariadb
Suppose you have a table table1 with col1 and other table2 with col1 and you want to list all row in table1 whose col1 values exist in table2.
We could code this as:
select *
from table1
where col1 in (
select col1 from table2
)
The result contains the expected rows if all data in col1 in table2 are not null.
However, if any values from table2 are null then it returns no rows.
This is unexpected to me and scary as I've used this clause many times.
This is how in is defined to work in SQL: if any of the values in the list used by in are null, none match.
See "Law of the excluded fourth" section of https://en.wikipedia.org/wiki/Null_(SQL) for more info.
All SQL databases behave this way.
I normally use exists, so I haven't struck this problem
select * from table1 t1
where exists (select t2.col1 from table2 t2
where t2.col1 = t1.col1)
Not Tested
I must write a Query like this in MySQL:
SELECT *
FROM Tab1
EXCEPT
SELECT *
FROM Tab1
WHERE int_attribute_of_Tab1>0
but MySQL doesn't support the keyword EXCEPT.
Is there a standard mode to use correctly another operator that simulate the except in MySQL?
You could use NOT IN
SELECT *
FROM Tab1
WHERE id NOT IN (
SELECT id
FROM Tab1
WHERE int_attribute_of_Tab1>0
)
Try this
SELECT *
FROM Tab1
WHERE [....] NOT EXISTS
(SELECT *
FROM Tab1
WHERE int_attribute_of_Tab1>0)
A couple of definitions
SqlServer https://learn.microsoft.com/en-us/sql/t-sql/language-elements/set-operators-except-and-intersect-transact-sql EXCEPT
Returns any distinct values from the query to the left of the EXCEPT operator that are not also returned from the right query.
PLsql https://docs.oracle.com/cd/B19306_01/server.102/b14200/queries004.htm MINUS
statement combines results with the MINUS operator, which returns only unique rows returned by the first query but not by the second
A pedantic translation to mysql would be
SELECT distinct t1.*
FROM Tab1 as t1
left outer join
(SELECT *
FROM Tab1
WHERE int_attribute_of_Tab1>0) as t2 on t1.id = t2.id
where t2.id is null;
Assuming there is an id column, And I wouldn't like to use distinct on a lot of columns.
You can use multiple NOT IN operators combined with AND operators for multiple columns.
For example:
SELECT col1, col2 FROM table1 WHERE col1 NOT IN(SELECT col1 FROM table2) AND col2 NOT IN(SELECT col2 FROM table2)...;
Since MySQL version 8.0.31 update, the EXCEPT operator has become available to use in this DBMS. If you are allowed to update your MySQL version, you are free to use the notation:
SELECT * FROM Tab1
EXCEPT
SELECT * FROM Tab1
WHERE int_attribute_of_Tab1>0
If Tab1 has a primary key (f.e. ID) then you could use a NOT EXISTS to itself like this :
SELECT *
FROM Tab1 AS t1
WHERE NOT EXISTS (
SELECT 1
FROM Tab1 AS t2
WHERE t2.ID = t1.ID
AND t2.int_attribute_of_Tab1 > 0
)
But it's kinda pointless in this case.
And it's not what an EXCEPT/MINUS tries to do.
(excluding identical rows)
The question's query with the EXCEPT uses the same table twice.
So reversing that WHERE criteria on Tab1 would give the same results.
SELECT *
FROM Tab1
WHERE (int_attribute_of_Tab1 <= 0 OR int_attribute_of_Tab1 IS NULL)
If it were 2 different tables then this
SELECT t1col1, t1col2, t1col3
FROM Table1
EXCEPT
SELECT t2col4, t2col5, t2col6
FROM Table2
WHERE int_attribute_of_Tab1 > 0
Could be replaced by comparing each selected column
SELECT DISTINCT t1col1, t1col2, t1col3
FROM Table1 AS t1
WHERE NOT EXISTS (
SELECT 1
FROM Table1 AS t2
WHERE t2.t2col4 = t1.t1col1
AND t2.t2col5 = t1.t1col2
AND t2.t2col6 = t1.t1col3
AND t2.int_attribute_of_Tab1 > 0
)
I have a query like this:
UPDATE t1
SET t1.col1 = ( SELECT col1 FROM t2 WHERE <some_complex_conditions> ),
t1.col2 = ( SELECT col2 FROM t2 WHERE <some_complex_conditions> )
WHERE id = :id;
As you see, I have to execute the same query twice, every time for one column. Also as I've mentioned, that SELECT query has some complex conditions which need lots of processing. Now I want to know, how can I handle the UPDATE statement to get the update those two columns by single SELECT statement?
Something like this:
SELECT col1, col2 FROM t2 WHERE <some_complex_conditions>
In other word, how can I use this ^ into the UPDATE statement?
see multi table syntax in manual and stackoverflow
It's possible to update joined table. I think that it should be possible to join select statement, but I'm not sure, but I think example below shows equivalent query:
UPDATE t1
LEFT JOIN t2
-- joining condition, there can be the part <some complex condition>
ON t1.id = t2.ref_id AND t2.col3 = 'whatever you want'
SET t1.col1 = t2.col1, t1.col2 = t2.col2
--additional condition like WHERE t2.col1 IS NOT NULL
IN mysql you have something like this:
Select * from (select * from t1, t2 where t1.c1=t2.c1 ) tbl1 ,tbl2
where tbl1.col1=tbl2.col2;
is there anything in like this in oracle, because when I am trying to do same thing in oracle I am getting this error :
invalid identifier "tbl1"."col1".
Try this way:
Select tbl1.col1
from (select c1 as col1 from t1, t2 where t1.c1=t2.c1 ) tbl1 ,tbl2
where tbl1.col1=tbl2.col2;
Here you can find more information.
Try this:
Select tbl1.*, tbl2.*
from (
select t1.c1 as col1, t2.* from t1, t2 where t1.c1=t2.c1
) tbl1 ,tbl2
where tbl1.col1=tbl2.col2;
Because you join 2 tables * doesn't work. Use tbl1.* and tbl2.* instead.
As already suggested by Parado you also have to rename t1.c1 to col1 in your inner select.
I am using mysql and I'm interested in rows where reciprocals appear in a different row in the table.
Imagine 2 columns, each with letters a through z.
Lets say row1 has a,b, row2 has a,c, and row 3 has c,a. I am interested in the pair a,c because it appears both as c,a and a,c in different rows in the table.
Do I have to use a nested select? Or perhaps an exists clause?
I believe this is what you're after, a self-join:
SELECT t1.*
FROM table1 t1
JOIN table1 t2
ON t1.col1 = t2.col2
AND t1.col2 = t2.col1
Here is a SQL fiddle demo: SQL Fiddle
also use SELECT REVERSE('abc') see http://dev.mysql.com/doc/refman/5.0/en/string-functions.html#function_reverse with above #spencer7593 said
`SELECT t1.*
FROM table1 t1
JOIN table1 t2
ON t1.col1 = t2.col2
AND t1.col2 = t2.col1`