consider my scenario like i have 3 tables
table1,
table2,
table3 i want to fetch some colums from table2 or table3 on the basis of some condition
like
select tb1.*,
if(tb1.status='true' then tb2.name else tb3.name)
from table1 tb1, table2 tb2, table3 tb3
where tb1.aid=tb2.aid and tb1.aid=tb2.aid
in short i want to display some column from either table2 or table3 on the basis of condition
You can use CASE EXPRESSION :
SELECT tb1.*,
CASE WHEN tb1.status = 'true' THEN tb2.name ELSE tb3.name END as `name`
FROM table1 tb1
INNER JOIN table2 tb2
ON(t1.aid = tb2.aid)
INNER JOIN table3 tb3
ON(tb1.aid = tb3.aid)
Or with IF() like you wanted :
SELECT tb1.*,
IF(tb1.status='true' ,tb2.col1,tb3.col1) as col1,
IF(tb1.status='true' ,tb2.col2,tb3.col2) as col2,
IF(tb1.status='true' ,tb2.col3,tb3.col3) as col3
.....
Also, try to avoid the use of implicit join syntax(comma separated) and use the proper syntax of a join, this will help you avoid mistakes like the one you did (compared both conditions to tb2 instead of one to tb2 and one to tb3
if(tb1.status='true',tb2.name,tb3.name) as name
SELECT
tb1.*
, CASE
WHEN tb1.status = 'true' THEN tb2.name
ELSE tb3.name
END AS var_name
FROM table1 tb1
INNER JOIN table2 tb2 ON tb1.aid = tb2.aid
INNER JOIN table3 tb3 ON tb2.aid = tb3.aid
Use a case expression
BUT, you also need to look hard at how you are joining the tables. There are 2 things to note:
stop using comma separated lists of tables, there is a more precise syntax available for joins
you currently (in the question) don't have a proper join to table3
Related
I have a query that selects all the data from one table and specific columns from another where two columns are equal and another column equals a specific value.
SELECT table1.*, table2.column1, table2.column2 FROM table1
INNER JOIN table2 ON table1.column3=table2.column3
WHERE table1.column1='foo';
Is it possible to pull table3.column1 & table3.column2 from a table3 where table3.column3=table1.column3 AND table3.column4='bar' ?
The thing that makes it more complex is that the data in table3 is optional and may not always exist; however I still want the query to return table1 & table2's data but with table3.column1 & table3.column2 just being presented as NULL or EMPTY...
Im struggling to get my head around it myself, and any insight or assistance would be greatly appreciated.
Use left join:
SELECT table1.*, table2.column1, table2.column2, table3.column1, table3.column2
FROM table1
INNER JOIN table2
ON table1.column3 = table2.column3
LEFT JOIN table3
ON table3.column3 = table1.column3 AND table3.column4 = 'bar'
WHERE table1.column1 = 'foo';
When there is no corresponding record in table3 table3.column1 and table3.column2 will be null
And if column1 and column2 names are not unique column names in select clause you need to give them an alias
select t1.col1, t2.col2, t3.col3
from table1 as t1
inner join table2 as t2 on t2.col3.t1.col2
left join table3 as t3 on t3.col3.t2.col2
where t1.col1 = 'test';
it can be done like this.
I have a fairly complex situation where I'd like to see if there is a single query I can use to get the data.
In the following pseudo code, assume the "*" in each select clause has the appropriate columns selected and that table3 and table4 have similar enough columns that I can handle the diffs with padding/fake columns.
select * from table1 where ActiveFlag=1
for each row returned (as A)
//check if member has a record in membership table
select * from table2 where MembershipId=A.MembershipId
if (row exists)
select * from table3 where MemberId=A.MemberId
else
select * from table4 where MembershipId=A.MembershipId
end of for loop
This assumne each row in TableA can have 0-1 membership, otherwise we need to filter duplicates first.
SELECT CASE WHEN M.MembershipId IS NULL
THEN T4.field1
ELSE T3.field1
END as field1,
....
CASE WHEN M.MembershipId IS NULL
THEN T4.fieldN
ELSE T3.fieldN
END as fieldN
FROM TableA A
LEFT JOIN Membership M
ON A.MembershipId = M.MembershipId
CROSS JOIN table3 T3
CROSS JOIN table4 T4
WHERE A.MemberId = T3.MemberId
OR A.MembershipId = T4.MembershipId
If you have duplicate Membership replace the first two JOIN with something like this.
FROM (
SELECT DISTINCT TableA.*, M.MembershipId
FROM TableA A
LEFT JOIN Membership M
ON A.MembershipId = M.MembershipId
) A
CROSS JOIN ..
I have 2 tables t1 and t2. Each have a customer ID column. What I am looking for is to join the 2 columns and SUBTRACT the duplicates.
My EG:
Table1 and Table2 with the IDs for each
I have tried a union query. The result I am left with is ID = 1,2,3,4,5,6,7,8,9,10. Where, what I'm after is subtracting 1-5 from Table2 and the result = 6,7,8,9,10.
I hope that makes sense and that someone is able to help. Sorry if this is a bit too simple compared to what you're all used to.
In SQL Server you can use the EXCEPT operator:
select ID
from Table2
except
select ID
from Table1
Mysql does not support it though. Using a an in clause or a left join would work in both servers:
--Using In clause
SELECT ID
FROM Table2
WHERE ID NOT IN
(
SELECT ID
FROM Table1
);
--Using join
SELECT Table2.ID
FROM Table2
left join Table1
on Table2.ID = Table1.ID
where Table1.ID is null
Use left outer join
select * from t1 left outer join t2 on t1.customerid = t2.customerid
I have 5 Tables like this:
TABLE 1: PRIMARY_KEY,NAME,FK_TABLE2
TABLE 2: PRIMARY_KEY,FK_TABLE3
TABLE 3: PRIMARY_KEY,FK_TABLE4
TABLE 4: PRIMARY_KEY,FK_TABLE5
TABLE 5: PRIMARY_KEY,DIAGRAM_NAME
And what I want is when I search for a name in a search bar, it returns Name from Table1, and also DIAGRAM_NAME from table 5.
The first part is easy:
SELECT `TABLE1`.name
from Table 1
Where `TABLE1`.name LIKE '%$search%'
But for the second part I need your help...
Thank you!
You need to look into using JOIN:
SELECT T.Name, T5.Diagram_Name
FROM Table1 T
JOIN Table2 T2 ON T.FK_TABLE2 = T2.PRIMARY_KEY
JOIN Table3 T3 ON T2.FK_TABLE3 = T3.PRIMARY_KEY
JOIN Table4 T4 ON T3.FK_TABLE4 = T4.PRIMARY_KEY
JOIN Table5 T5 ON T4.FK_TABLE5 = T5.PRIMARY_KEY
WHERE T.Name LIKE '%$search%'
If you want to return the names that don't have matching diagram names, use LEFT JOIN instead.
Good luck.
You are going to need to JOIN the tables using the Primary Key and FK values:
select t1.name, t5.DIAGRAM_NAME
from table1 t1
left join table2 t2
on t1.FK_TABLE2 = t2.PRIMARY_KEY
left join table3 t3
on t2.FK_TABLE2 = t3.PRIMARY_KEY
left join table4 t4
on t3.FK_TABLE3 = t4.PRIMARY_KEY
left join table5 t5
on t4.FK_TABLE4 = t5.PRIMARY_KEY
Where t1.name LIKE '%$search%'
If you need help learning JOIN syntax, here is a great visual explanation of joins.
I used a LEFT JOIN in my example query, which will return all rows from table1 even if there is not a matching row in the remaining tables.
If you know that there is a matching row in all of the tables that you are joining, then you can use an INNER JOIN.
I have the following query:
SELECT col1, col2, col3 FROM tb1
WHERE col4=ANY(
SELECT col1 FROM tb2
WHERE col2=(SELECT col1 FROM tb3 WHERE col3='php generated string')
AND col3=(SELECT col2 FROM tb3 WHERE col3='same string as above')
);
It works, but it's very slow. I know there is a much better (and faster) way to do this, but my lack of experience with SQL queries means I'm trying to make this harder than it needs to be. I've tried using a JOIN, but I don't truly understand how to make that work in this case either.
Any help is much appreciated.
You're right that you need to learn how to use JOIN. If you ever are matching up values from one column across multiple tables, you should probably be JOINing the tables together ON that column.
SELECT tb1.col1,tb1.col2,tb1.col3
FROM tb1
JOIN tb2
ON (tb1.col4 = tb2.col1)
JOIN tb3
ON (tb1.col2 = tb3.col1
AND tb1.col3 = tb3.col2)
WHERE tb3.col3 = 'php generated string'
SELECT tb1.col1, tb1.col2, tb1.col3
FROM tb1
INNER JOIN tb2
ON tb1.col4 = tb2.col1
INNER JOIN tb3
ON tb1.col2 = tb3.col1
AND tb3.col3 = 'php generated string'
INNER JOIN tb3
ON tb1.col3 = tb3.col2
AND tb3.col3 = 'same string as above'
If the subquery within ANY can return more than one record, then rewriting your query as a JOIN will result in duplicates.
Use this:
SELECT col1, col2, col3
FROM tb1
WHERE EXISTS
(
SELECT NULL
FROM tb3
JOIN tb2
ON tb2.col2 = tb3.col1
AND tb2.col2 = tb3.col2
AND tb2.col1 = tb1.col4
WHERE tb3.col3 = 'php generated string'
)
and create the following indexes:
tb2 (col1, col2, col3)
tb3 (col3)