How can I query this in a database? - sql

I have 2 tables
Table 1
Positon | Name | Nickname | Address
------------------------------------
1 | 2 | 3 | 4
5 | 6 | | 7
5 | 6 | | 8
Table 2
Detail_seq | Details
--------------------
1 | manager
2 | Jimmy
3 | Jim
4 | Chicago
5 | Supervisor
6 | Mike
7 | Vancouver
8 | New York
and the output should be like this or something
Position: Manager
Name: Jimmy
Nickname: Jim
Address: Chicago
Position: Supervisor
Name: Mike
Nickname:
Address: Vancouver and New York
feel free to ask questions if it is not clear.
thanks in advance

I think this is what you want:
SELECT Position=manager.details,
Name=Name.details,
Nickname=Nickname.details,
Address=Address.details
FROM table1 t1
LEFT OUTER JOIN table2 manager
ON t1.positon = manager.detail_seq
LEFT OUTER JOIN table2 name
ON t1.name = name.detail_seq
LEFT OUTER JOIN table2 Nickname
ON t1.nickname = Nickname.detail_seq
LEFT OUTER JOIN table2 Address
ON t1.address = Address.detail_seq
DEMO

It's a little bit extreme to store data this way. I can offer you to store the data categories in different tables. but if you insist, this should work
SELECT d1.details, d2.details, d3.details, d4.details
FROM main m, details d1, details d2, details d3, details d4
WHERE m.position = d1.detail_seq
AND m.name = d2.detail_seq
AND m.nickname = d3.detail_seq
AND m.adress = d4.detail_seq

You need to join the details table one time for every detail:
SELECT pos.Details, name.details, nick.details, adress.details
FROM table1 t1
LEFT JOIN table2 pos ON pos.detail_seq = t1.position
LEFT JOIN table2 name ON name.detail_seq = t1.name
LEFT JOIN table2 nick ON nick.detail_seq = t1.nickname
LEFT JOIN table2 address ON address.detail_seq = t1.address

select (select details from t2 where t2.detail_seq=t1.position) position,
(select details from t2 where t2.detail_seq=t1.name) Name,
(select details from t2 where t2.det_seq=t1.nickname) nickname,
(select details from t2 where t2.det_seq=t1.address) address
from t1 ;

Related

How to join a table with itself based on a foreign key in same table?

Let's say I have a SQL table as follows:
Id | Name | Email | Id_manager
---+------+--------------+------------
1 | Jon | jon#foo.com | 2
2 | Mike | mike#foo.com | 2
2 | Bar | bar#foo.com | 1
So here Jon is the manager of Bar and mike is the manager of John and himself. So Id_manager is a foreign key that references the same table.
I need to return a new table containing the following columns
Name, Email, Manager_Name
But I have no clue how to get the name of the manager using a SQL operation. Should I use a join? If so how can I do it in this case?
That's a self-join indeed:
select t.name, t.email, m.name as manager_name
from mytable t
inner join mytable m on m.id = t.id_manager
If there are employees without a manager, you might want to use left join instead of inner join to avoid filtering them out.
I think the answer can also be put in this way:
select t1.name, t1.email, t2.name as manager_name from mytable t1, mytable t2
where t1.id_manager = t2.id
I think the Id column should be unique, so I change the Id of Bar from 2 to 3.
The following can tell you the result when the id_manager column in t1 is equal to the Id column in t2.
t1 t2
Id|Name|Email |Id_manager Id|Name|Email |Id_manager
1 |Jon |jon#foo.com |2 2 |Mike|mike#foo.com|2
2 |Mike|mike#foo.com|2 2 |Mike|mike#foo.com|2
3 |Bar|bar#foo.com |1 1 |Jon |jon#foo.com |2

Update column with specific values ( if clause)

I am trying to insert new values into specific column with "update table set specific column...."
I have two tables like this:
Table1
Name Idnumber Score
JOHN DB 10
JOHN IT NULL
KAL DB 9
HENRY KK 7
KAL DB 10
HENRY IP 9
ALI IG 10
ALI PA 9
Table2
NAME | MONEY |
-----------------|
JOHN | |
-----------------|
KAL | |
-----------------|
HENRY | |
-----------------|
ALI | |
-----------------
And I want that my table look like this:
Updated Table
NAME | MONEY |
-----------------|
JOHN | |
-----------------|
KAL | yes |
-----------------|
HENRY | half |
-----------------|
ALI | yes |
-----------------
The condition for writing "yes" into money column is that all scores under same name in table1 should be 9 or higher, the condition for writing "half" is that scores should be no lower than 6 ( what I mean is that scores might be 10,9,8,7 and 6)
So basically it means, that, for example, Henry cannot be selected and I cannot write "yes" next to his name in updated table, because he has score under the value of 9 in one line , but in the other he has the score of 7.(null values also should be emitted).
I'm using a sas program. Thank you!!!
You seem to be treated NULL as a value that is less than "9". In standard SQL (which works in both MySQL and SAS, the original tags) is:
update table2 t2
set money = 'YES'
where not exists (select 1
from table1 t1
where t1.name = t2.name and coalesce(t1.score, 0) < 9
);
If you want to guarantee that there is at least one row in table2, one method is aggregation:
update table2 t2
set money = 'YES'
where (select (case when sum(case when t1.score > 9 then 1 else 0 end) = count(*)
then count(*)
end)
from table1 t1
where t1.name = t2.name
) > 0
You could try the following syntax:
update table2
set money = 'YES'
where not exists (select 1 from table1 t1 where t1.name = table2.name and t1.score < 9)
However this would also update records that have no match in table1. In MySQL, one simple option to avoid that uses a join:
update table2 t2
inner join (select name, min(score) min_score from table1 group by name) t1
on t1.name = t.name and t1.min_score >= 9
set t2.money = 'YES'

Select Minus with fixed column in Oracle sql

I'd like to do a MINUS operation between two tables like these:
table1:
employee_id | job | sector
----------- | ------ | ------
10 | a | 1
10 | a | 2
10 | b | 4
table2:
job | sector
---- | ------
a | 1
a | 2
a | 3
b | 1
b | 4
c | 1
c | 2
and as result I want, for every employee_id, the {job,sector} not connected in table1.
RESULT:
employee_id | job | sector
----------- | --- | ------
10 | a | 3
10 | b | 1
10 | c | 1
10 | c | 2
Is it possible?
I hope I have written in a clear way! Thanks!
First select the complete data set, i.e. employee_id X job/sector. From these remove the existing table1 entries to get the lacking ones. (I've renamed your table table2 to job_sector for readability. I also suppose you have an employee table.)
select e.employee_id, js.job, js.sector
from employee e
cross join job_sector js
minus
select employee_id, job, sector
from table1;
Left join, where t2 is null
select t1.*
from table1 t1
let join table2 t2
on t1.job = t2.job
and t1.sector = t2.sector
where t2.job is null
This sounds like just a left join (or not in or not exists):
select 10 as employee_id, t2.*
from table2 t2 left join
table1 t1
on t2.job = t1.job and t2.sector = t1.sector
where t1.job is null;
I am a bit confused on how you get the employee id if the tables are not linked.
If you have multiple employees in t1, then you can do:
select e.employee_id, t2.*
from (select distinct employee_id from t1) e cross join
table2 t2 left join
table1 t1
on t2.job = t1.job and t2.sector = t1.sector and
e.employee_id = t1.employee_id
where t1.job is null;
You can simply achieve it by doing a left join. You query will look something like this:
SELECT T2.*
FROM TABLE2 T2 LEFT JOIN
TABLE1 T1
ON T2.JOB = T1.JOB AND T2.SECTOR = T2.SECTOR
WHERE T1.JOB IS NULL;
Though table must be linked in order to get the employee id.

SQL combining two tables without duplication

I want to combine two tables based on a column. Here's an example:
These are my two tables:
Table1 Table2
Person | salary Person | Age
Tim | 22.50 Larry | 32
Tony | 49.00 Tim | 22
John | 32.67 Tony | 44
Kim | 23.42 John | 31
And my resulting table should be:
Person | salary | Age
Larry | | 32
Tim | 22.50 | 22
Tony | 49.00 | 44
John | 32.67 | 31
Kim | 23.42 |
Everyone is added to the resulting table only once even if they don't have a value for both salary and age
Thanks in advance!
Since you have tagged this as MS-ACCESS I will provide SQL code for MS ACCESS
Because Microsoft does not have the capability to do a FULL OUTER JOIN, you have to think of a clever way to use existing SQL commands to create a FULL OUTER JOIN. The following code should do the trick using your tables above:
SELECT Table1.Person, Salary, Age
FROM Table1 INNER JOIN Table2 ON Table1.Person = Table2.Person
UNION ALL
SELECT Table1.Person, Salary, Age
FROM Table1 LEFT JOIN Table2 ON Table1.Person = Table2.Person
WHERE Table2.Person Is Null
UNION ALL
SELECT Table2.Person, Salary, Age
FROM Table1 RIGHT JOIN Table2 ON Table1.Person = Table2.Person
WHERE Table1.Person Is Null
This could have been done by full outer join but since you are using ms access you will have to use union all in the below manner.
Try this out and let me know in case you face any difficulties.
SELECT * FROM table1 t1
LEFT JOIN
table2 t2
ON t1.person = t2.person
UNION all
SELECT * FROM table1 t1
RIGHT JOIN
table2 t2
ON t1.person = t2.person
I don't see what's your problem exactly but here is a SQL query that will do just what you have requested:
SELECT Person, salary, Age
FROM Table1 FULL OUTER JOIN Table2
WHERE Table1.Person = Table2.Person
Edit: This won't work on MS-ACCESS for its lack of support for FULL OUTER JOINS, the other two answers have explained the alternative.

sql query join where none of the many meet a condition

I have 3 tables. On the first table, there are multiple entries for each project. The second is basically a mapping table. It's more complicated than this, but for this example I've simplified. There's a simple condition I'm checking for on table 2. On the third table, each entry has a flag that's set to true or false. I want to return rows on the first table where all matching rows on the third table are false. In the example below, the result would return project A b/c all of Jane and Fred's rows in table 3 are false, but none of the other's since every other project has at least one true entry in table 3.
Project | Client name | id id | active
--------------- ---------------- ---------------
A | Jane John | 1 1 | false
A | Fred Jane | 2 1 | true
B | Mary Fred | 3 2 | false
B | Jane Mary | 4 2 | false
C | John 3 | false
C | Jane 3 | false
D | Jane 4 | true
D | Mary 4 | false
D | John
D | Fred
The following should do what you want:
select t1.*
from table1 t1
where not exists (select 1
from table2 t2 join
table3 t3
on t2.id = t3.id
where t2.name = t1.name and t3.active <> false
);
There is some ambiguity about what to do when one of the joins fails (this condition is not present in the sample data). This will return the row, because all matching rows in the third table are false, even in that case.
SELECT t1.* FROM t1
INNER JOIN t2 ON t1.Client = t2.name
WHERE t2.id IN (
SELECT id FROM t3
GROUP BY id, active
HAVING SUM(CASE active WHEN false THEN 1 ELSE 0 END) = COUNT(1)
)
A fairly straight forward JOIN with HAVING should give you the results you want;
SELECT t1.project, t1.client
FROM table1 t1
JOIN table2 t2 ON t1.client = t2.name
JOIN table3 t3 ON t2.id = t3.id
GROUP BY t1.project, t1.client
HAVING NOT MAX(t3.active)
An SQLfiddle to test with.
This basically just does a straight forward join of all tables, groups the results by client and project. It then uses NOT MAX(t3.active) to check that all booleans in the group are false.
This version chooses to not return clients/projects that don't have any active flags to check.
You have to do the select from the first table with two joins and a simple WHERE condition:
SELECT
res.Project
FROM
(SELECT
table1.Project,
BOOL_OR(res) as active
FROM
table1
JOIN table2 ON table2.name=table1.Client
JOIN table3 ON table3.id=table2.id
GROUP BY table1.Project
) as res
WHERE
res.active=FALSE