The have the following 2 table2:
Table1(col1 integer, col2)
1 "This is a string"
2 "This is another string"
5 "This is yet another string"
3 "a"
4 "b"
6 "Some other string"
Table2(col3 integer, col4 integer, col5 integer)
1 2 5
3 4 6
Now I want to find all the values from Table2 where col4=2. This gives me col3=1 and col5=5. Now I want to join this result with Table1 such that I obtain the string values(col2) corresponding to these integers.
That is, I want the result as: "This is a string", "This is yet another string"
The SQL query which I wrote in postgresql is given below:
select d1.col2, d2.col2
from Table1 d1, Table1 d2
where (select col3, col5 from Table2 where col4=0);
However, the above query is giving me error. Can someone please help me write an efficient query for the same.
You could use an INNER JOIN with two conditions on the ON clause:
SELECT Table1.*
FROM
Table1 INNER JOIN Table2
ON Table1.col1 = Table2.col3 OR Table1.col1 = Table2.col5
WHERE
Table2.col4=2
Please see fiddle here.
Try
SELECT t2.col2, t3.col2
FROM Table1 AS t1
INNER JOIN Table2 AS t2 ON t1.col1 = t2.col3
INNER JOIN Table2 AS t3 ON t1.col1 = t2.col5
WHERE t1.col4 = 2
if you want your result as two rows with one column:
select t1.col2
from Table2 as t2
inner join Table1 as t1 on t1.col1 in (t2.col3, t2.col5)
where t2.col4 = 2;
-- output
-- 'This is a string'
-- 'This is yet another string'
if you want your result as one row with two columns:
select t13.col2, t15.col2
from Table2 as t2
inner join Table1 as t13 on t13.col1 = t2.col3
inner join Table1 as t15 on t15.col1 = t2.col5
where t2.col4 = 2
-- output
-- 'This is a string', 'This is yet another string'
sql fiddle demo
try it as a union
select col2 from table1 where col1 in (
select col3 from table2 where col4 = 2
union
select col5 from table2 where col4 = 2
)
Related
I have to make a SQL query wraping all of theses statements:
First, I have a first SQL query like this:
SELECT COUNT(*) as NbOfEntries from table1 where colName = "some condition"
Then, I have another SQL statement like this:
SELECT
t2.col1 as col1,
t2.col2 as col2,
t3.col3 as col3
FROM table2 t2
INNER JOIN table3 t3
ON t2.colName = t3.colName
WHERE t2.colName = "some condition"
Finally, based on the first SQL statement, I have to add a row of fake data on the result of the second statement if NbOfEntries > 0. I have to add an UNION to the second SQL query like this:
SELECT
"Dumb string 1" as col1,
"Dumb string 2" as col2,
"Dumb string 3" as col3
FROM DUAL -- or something like that, I don't know how it works
I thought about using UNION but, I don't know how to use UNION with a condition. In addition, I do not know how to generate fake data with SELECT in Oracle, I have already looked at how DUAL works but I have not really been able to move forward.
Thank you.
EDIT: Sample data
If the first statement returns 0, I have these rows:
col1 col2 col3
A AB 3
A AC 7
A AD 2
If the first statement returns > 0, I ihave to add one fake row to the result like this:
col1 col2 col3
A AB 3
A AC 7
A AD 2
X XX 0 // << Add this last row
You can use EXISTS like this:
SELECT
t2.col1 as col1,
t2.col2 as col2,
t3.col3 as col3
FROM table2 t2
INNER JOIN table3 t3
ON t2.colName = t3.colName
WHERE t2.colName = "some condition"
UNION ALL
SELECT
"Dumb string 1" as col1,
"Dumb string 2" as col2,
"Dumb string 3" as col3
FROM DUAL
WHERE EXISTS (
SELECT 1 from table1
where colName = "some condition"
)
There is no need to count the rows of table1.
EXISTS will return TRUE if there is 1 row that meets the condition.
You could jut use a HAVING clause for filtering:
SELECT t2.col1 as col1, t2.col2 as col2, t3.col3 as col3
FROM table2 t2
INNER JOIN table3 t3 ON t2.colName = t3.colName
WHERE t2.colName = 'some condition'
UNION ALL
SELECT 'X', 'XX', 0
FROM table1
WHERE colName = 'some condition'
HAVING COUNT(*) > 1
table 1
col1 col 2
A aaa
B bbb
C ccc
table 2
col1 col 2 col3
A aaa xx
B bbb yy
C ccc zz
D ddd hh
E eee mm
How to write a query where i get all of table1 data and only col3 to existing records of Table 1. table1 has only 50 records and Table2 has 100k. But i need only all 50 records of Table 1 and only col3 added to the record by joining
table1. col1 = table2.col1
Based on the description, I would suggest this query:
SELECT
t1.col1,
t2.col2,
t2.col3
FROM
table1 AS t1
INNER JOIN
table2 AS t2 ON (t2.col1 = t1.col1 AND t2.col2 = t1.col2)
The SELECT clause determines what columns will appear in the result set. Your description gives us some assistance here.
For a join, choosing the correct join type is important to what query you are making. Your description is helpful for this:
How to write a query where I get all of table1 data and only col3 to existing records of Table 1.
“get all of table1” implies that the result set should include all columns from that table.
SELECT table1.col1, table1.col2 […]
“get all of table1” implies that table1 is the primary source in the FROM clause.
[…] FROM table1 […]
“only col3 [from table2]” implies that the result set should also include that column.
SELECT […] table2.col3
“only […] to existing records of table1” implies that the join type is INNER JOIN.
FROM table1
INNER JOIN table2 […]
“only col3 to existing records of table1” implies that is the join condition.
FROM table1
INNER JOIN table2 ON table2.[…] = table1.[…]
But you don't specify exactly what condition tells us what records are equivalent between the tables. Shall we assume that the condition is for all columns named the same to have the same value?
FROM table1
INNER JOIN table2 ON (table2.col1 = table1.col1 AND table2.col2 = table1.col2)
We will be using the tables several times, so it's good practice to set concise AS aliases in the FROM clause.
You want INNER JOIN :
SELECT t1.col1, t1.col2, t2.col3
FROM table1 t1 INNER JOIN
table2 t2
ON t2.col1 = t1.col1;
Try left join:
SELECT t1.col1, t1.col2, t2.col3
FROM table1 t1 LEFT JOIN
table2 t2
ON t1.col1 = t2.col1 AND t1.col2 = t2.col2;
Data is like so, (table1 links up to table2) on table1.col2 = table2.col2
Based on that criteria,
Employee 5 below assigned to Area 1 in first table, however in second table that employee is not assigned to Area 1, so the result that would return would only be the first record of the first table (emp5, a1)
Example below
Table1
Col1 Col2
-------------
emp5 A1
emp6 A1
emp5 A2
Table2
Col1 Col2
--------------
emp7 A1
emp6 A1
emp5 A2
You can use MINUS, it is more intuitive. The syntax can be different in SQL Server, MySQL or Oracle, like you can see http://blog.sqlauthority.com/2008/08/07/sql-server-except-clause-in-sql-server-is-similar-to-minus-clause-in-oracle/
But I like MINUS, for instance
select
t1.Col1,
t1.Col2
from table1 t1
MINUS
select
t2.Col1,
t2.Col2
from table2 t2
This way, you can think like sets (math)!
This is tricky. You need employees who are in both tables. Then you need to check that col2 is different on one of the rows.
The following does this comparison using union all:
select col1, col2, max(which)
from ((select col1, col2, 1 as which
from table1 t1
where exists (select 1 from table2 t2 where t2.col1 = t1.col1)
) union all
(select col1, col2, 2 as which
from table2 t2
where exists (select 1 from table1 t1 where t2.col1 = t1.col1)
)
) tt
group by col1, col2
having count(*) = 1
This will also tell you which table has the extra row.
select table1.*
from table1
left join table2
on table1.col1 = table2.col1
and table1.col2 = table2.col2
where table2.col1 is null
if you only want those from table 1 that are also assigned to another project then
select distinct table1.*
from table1
join table2 as t2not
on t2not.col1 = table1.col1
and t2not.col2 <> table1.col2
left join table2
on table1.col1 = table2.col1
and table1.col2 = table2.col2
where table2.col1 is null
I was wondering if there exists code to accomplish the following in SQL-Server 2008?
Table 1:
id column name
-------------------
1 col1
2 col2
3 col3
4 col2
Table 2:
col1 col2 col3
--------------------
a b c
Result Table:
id data
--------------------
1 a
2 b
3 c
4 b
Thanks in advance, I really have no idea how to do this.
You can use UNPIVOT table2 to access the data from the columns:
select t1.id, t2.value
from table1 t1
left join
(
select value, col
from table2
unpivot
(
value
for col in (col1, col2, col3)
) u
) t2
on t1.name = t2.col
see SQL Fiddle with Demo
Or you can use a UNION ALL to access the data in table2:
select t1.id, t2.value
from table1 t1
left join
(
select col1 value, 'col1' col
from table2
union all
select col2 value, 'col2' col
from table2
union all
select col3 value, 'col3' col
from table2
) t2
on t1.name = t2.col
see SQL Fiddle with Demo
I dont see how you do it withou a column connection them:
Table1:
ID
ColumnName
Table2:
Table1ID
Letter
Select table1.id, table2.Letter
from table1
inner join table2 on table1.ID = table2.Table1ID
You can do this with a case statement and cross join:
select t1.id,
(case when t1.columnname = 'col1' then t2.col1
when t1.columnname = 'col2' then t2.col2
when t1.columnname = 'col3' then t2.col3
end) as data
from table1 t1 cross join
table2 t2
I have 2 tables table A and table B. In table B we have to check if all the column entered is exactly as in table A, means if a row exists in table B then the same row will be there in table A too. also table A may have rows which are not in table B. if there is a row which is not in table A and is there in table B, an alert should be displayed showing which element is extra in table B.
Can we do this using join? if so what will be the sql code?
this is the best picture about joins i've ever seen :)
You probably want to have a look at the following article
SQL SERVER – Introduction to JOINs – Basic of JOINs
This should give you a very clear understanding of JOINs in Sql.
From there you should be able to find the solution.
As an example, you would have to look at something like
TABLE1
Col1
Col2
Col3
Col4
TABLE2
Col1
Col2
Col3
Col4
--all rows that match
SELECT *
FROM TABLE1 t1 INNER JOIN
TABLE2 t2 ON t1.Col1 = t2.Col1
AND t1.Col2 = t2.Col2
...
AND t1.Col3 = t2.Col3
--rows only in TABLE1
SELECT *
FROM TABLE1 t1 LEFT JOIN
TABLE2 t2 ON t1.Col1 = t2.Col1
AND t1.Col2 = t2.Col2
...
AND t1.Col3 = t2.Col3
WHERE t2.Col1 IS NULL
--rows only in TABLE2
SELECT *
FROM TABLE1 t2 LEFT JOIN
TABLE2 t1 ON t1.Col1 = t2.Col1
AND t1.Col2 = t2.Col2
...
AND t1.Col3 = t2.Col3
WHERE t1.Col1 IS NULL
If you want to compare based on single column, then you can do something like this:
SELECT ID FROM B LEFT JOIN A ON B.ID = A.ID WHERE A.ID IS NULL;
The above query will give you the list of records that are not present in A but in B.
Instead if you want to compare the entire row, you can use the following approach:
SELECT COUNT(*) FROM B;
SELECT COUNT(*) FROM A;
SELECT COUNT(*) FROM (
SELECT * FROM B UNION SELECT * FROM A
)
If all the queries returns the same count then you can assume that both the tables are exactly equal.