SQL JOIN table2 ON table2.value in (table1.value) - sql

I want to perform an inner join on a table, based on it's values, like this:
SELECT table2.value FROM table1
INNER JOIN table2 ON table2.key IN (table1.value)
WHERE table1.key = 'test'
Something with the in () is not working, the "in (table1.value)" is not being interpret as "in ('1','2')", it does not show any results.
table1:
KEY VALUE
test '1','2'
table2:
KEY VALUE
1 result1
2 result2
3 result3
I know there is a workaround like this, but I'd like to solve this without an additional SELECT..
SELECT * FROM table2 WHERE table2.value in (SELECT value FROM table1 WHERE key = 'test')
Any ideas?
Thanks,
Lennart

First, your data structure is simply wrong. You should not be storing lists of ids in a string. There are numerous good reasons:
SQL does not have good string processing functions.
You should not store integers as strings.
You should declare proper foreign key relationships.
Your queries cannot take advantage of indexes or partitioning.
The right solution is one row per key and per value.
However, sometimes, we are stuck with other people's really bad design decisions. In that case, you can use like:
SELECT table2.value
FROM table1 t1 INNER JOIN
table2 t2
ON t1.value LIKE '%''' + t2.key + '''%'
WHERE t1.key = 'test';

Related

DISTINCT COLUMN VALUES FROM ANOTHER TABLE IN JOIN

select t1.key,t2.design,t1.price,t1.gender,t1.store
from table1 t1,table2 t2
where t1.key=t2.key;
This is my query. In this query, column KEY is distinct. I need result with distinct DESIGN values. Help me with this.
from table1 t1 join table2 t2 on t1.key = t2.key
where design like "specific design"
Your request is not precise. There are two things possible:
1) You are talking about duplicate records, i.e. for two records with the same design the columns key, price, gender and store are guaranteed to be equal. Two ways to solve it:
select DISTINCT t1.key,t2.design,t1.price,t1.gender,t1.store
from table1 t1,table2 t2
where t1.key=t2.key;
or
select t1.key,t2.design,t1.price,t1.gender,t1.store
from table1 t1, (select distinct key, design from table2) t2
where t1.key=t2.key;
2) You are talking of duplicate designs and ambigious information related, i.e. for two records for the same design you may get different prices etc. Then you must think about what information you want to get per design. The maximum price? The sum of prices? ...
select t1.key,t2.design,sum(t1.price),max(t1.gender),max(t1.store)
from table1 t1,table2 t2
where t1.key=t2.key
group by t1.key,t2.design;
This gives you records per key and design. If you want records per design only then you would group only by design and decide which key you want to show with it.
A last recommendation: Use explicit join syntax. It is easier to read and less error-prone.
select t1.key, t2.design, t1.price, t1.gender, t1.store
from table1 t1
inner join table2 t2 on t1.key = t2.key;

Most Efficiently Written Query in SQL

I have two tables, Table1 and Table2 and am trying to select values from Table1 based on values in Table2. I am currently writing my query as follows:
SELECT Value From Table1
WHERE
(Key1 in
(SELECT KEY1 FROM Table2 WHERE Foo = Bar))
AND
(Key2 in
(SELECT KEY2 FROM Table2 WHERE Foo = Bar))
This seems a very inefficent way to code the query, is there a better way to write this?
It depends on how the table(s) are indexed. And it depends on what SQL implementation you're using (SQL Server? MySq1? Oracle? MS Access? something else?). It also depends on table size (if the table(s) are small, a table scan may be faster than something more advanced). It matters, too, whether or not the indices are covering indices (meaning that the test can be satisfied with data in the index itself, rather than requiring an additional look-aside to fetch the corresponding data page.) Unless you look at the execution plan, you can't really say that technique X is "better" than technique Y.
However, in general, for this case, you're better off using correlated subqueries, thus:
select *
from table1 t1
where exists( select *
from table2 t2
where t2.key1 = t1.key1
)
and exists( select *
from table2 t2
where t2.key2 = t1.key2
)
A join is a possibility, too:
select t1.*
from table1 t1
join table2 t2a = t2a.key1 = t1.key1 ...
join table2 t2b = t2b.key2 = t1.key2 ...
though that will give you 1 row for every matching combination, though that can be alleviated by using the distinct keyword. It should be noted that a join is not necessarily more efficient than other techniques. Especially, if you have to use distinct as that requires additional work to ensure distinctness.

SQL query, where = value of another table

I want to make a query that simply makes this, this may sound really dumb but i made a lot of research and couldn't understand nothing.
Imagine that i have two tables (table1 and table2) and two columns (table1.column1 and table2.column2).
What i want to make is basically this:
SELECT column1 FROM table1 where table2.column2 = '0'
I don't know if this is possible.
Thanks in advance,
You need to apply join between two talbes and than you can apply your where clause will do work for you
select column1 from table1
inner join table2 on table1.column = table2.column
where table2.columne=0
for join info you can see this
Reading this original article on The Code Project will help you a lot: Visual Representation of SQL Joins.
Find original one at: Difference between JOIN and OUTER JOIN in MySQL.
SELECT column1 FROM table1 t1
where exists (select 1 from table2 t2
where t1.id = t2.table1_id and t2.column2 = '0')
assuming table1_id in table2 is a foreign key refering to id of table1 which is the primary key
You don't have any kind of natural join between two tables.
You're asking for
Select Houses.DoorColour from Houses, Cars where Cars.AreFourWheelDrive = '1'
You'd need to think about why you're selecting anything from the first table, there must be a shared piece of information between tables 1 and 2 otherwise a join is pointless and probably dangerous.

Many SQL queries vs 1 complex query

I have a database with two tables that are similar to:
table1
------
Id : long, auto increment
Title : string(50)
ParentId : long
table2
------
Id : long, auto increment
FirstName : string(20)
LastName : string(30)
Zip : string(5)
table2 has a one-to-many relationship with table1 where many includes zero.
I also have the following query (that works correctly, so ignore typos an the like, it is an example):
SELECT t1.Id AS tid, t1.Title, t2.Id AS oid, t2.FirstName, t2.LastName
FROM table t1
INNER JOIN table2 t2 ON t1.ParentId = t2.Id
WHERE t2.Id IN
(SELECT Id FROM table2
WHERE Zip IN ('zip1', 'zip2', 'etc'))
ORDER BY t2.Id DESC
The query finds all items in table1 that belong to a person in table2, where the person is in one of the listed zip codes.
The problem I have now is: I want to show all the users (with their items if available) in the listed zip codes, not just the ones with items.
So, I am wondering, should I just do something simple with a lot more queries, like:
SELECT Id AS oid, FirstName, LastName FROM table2 WHERE Zip in ('zip1', 'zip2', 'etc')
foreach(result) {
SELECT Id AS tid, Title FROM table2 WHERE ParentId = oid
}
Or should I come up with a more elaborate single SQL statement? And if so, can I get a little help? Thanks!
If I understand correctly, changing your INNER JOIN to a RIGHT JOIN should return all users regardless of whether they have an item or not, the item columns will just be null for those that don't.
Look into Right Joins and Group By. That will most likely get you the query you are after.
I agree with (and have upvoted) #Lee D and #Bueller. However, I generally advocate LEFT OUTER JOINS, because I find it easier to conceptualized what's going on with them, particularly when you are joining three or more tables. Consider it like so:
Start with what you know you want in the final result set:
FROM table2 t2
and then add in the "optional" data.
FROM table2 t2
left outer join table1 t1
on t1.ParentId = t2.Id
Whether or not matches are found, whatever gets selected from table2 will always appears.
In general, you should prefer the "many queries" approach if (and only if)
it gets you simpler code in total
is fast enough (which you should find out by testing)
In this case, I suspect, both conditions may not apply.
You should come up with a more elaborate single SQL statement and then process the results with your favorite programming language.
What you've described is called an N + 1 query. You have 1 initial query that returns N results, then 1 query for each of your N results. If N is small, the performance difference may not be noticeable - but there will be a larger and larger performance hit as N grows.
If I understand correctly, I think you are looking for something like this
SELECT t1.Id AS tid, t1.Title, t2.Id AS oid, t2.FirstName, t2.LastName
FROM table t1
RIGHT OUTER JOIN table2 t2 ON t1.ParentId = t2.Id AND Zip IN ('zip1', 'zip2', 'etc'))
ORDER BY t2.Id DESC
You can have multiple conditions on your JOIN and RIGHT OUTER will give you all the rows in table2 even if they don't match in table1

Query related data based on "like" statement

I have two tables
Table1:
ColumnA (varchar)
Table2:
ColumnB (varchar)
I need to get all rows from T2 where ColumnB is "like" any of the rows from 'ColumnA%'. For example, rows in T1 might be:
Summer09
Fall09
while rows in T2 might be
Spring09 Com101 Sec1
Summer09 Stat400 Sec2
Fall09 CS200 Sec3
In that scenario it would retun the Stat400 and CS200 rows. Is there a way to do this in a single SQL statement?
SELECT T2.*
FROM T1, T2
WHERE T1.ColumnB LIKE T2.ColumnA + '%'
or
SELECT T2.*
FROM T1
INNER JOIN T2 ON T1.ColumnB LIKE T2.ColumnA + '%'
Probably not going to run very fast.
this question points to a bad table design. my good friend Codd always said: do not combine multiple pieces of information into a single column!
t1 coulm should be split, so the semester and/or year should be their own column(s) with a FKs to the t2 table where the class info can be found using an index and no a slow LIKE!!