Select Query Joining 3 Tables - sql

I've 3 Tables
Personel : id, name
Department : id, name
Match_Dept_Per : dept_id, pers_id, workInfo
Foreign Keys :
dept_id --> Department.id
pers_id --> Personel.id
Example Data :
Personel :
1, Emir Civas
2, Sercan Tuncay
Department :
1, Sales
2, Planning
Match_Dept_Per :
1,1,Manager
What I'm trying to do is, listing peoples names, their department names and workInfos like:
ID | Pers. Name | Dept Name | Work Info
---------------------------------------
1 | Emir Civas | Sales | Manager
I can do this with a simple select query:
select p.id, p.name, d.name, m.workInfo
from personel p, department d, match_dept_per m
where p.id = m.pers_id and d.id = m.dept_id;
Here is sample fiddle of my schema and this query.
However what I need is to display other persons that their id's are not inserted to match_dept_per table. And Set "Unknown" As the Null Values. Like:
ID | Pers. Name | Dept Name | Work Info
------------------------------------------
1 | Emir Civas | Sales | Manager
2 | Sercan Tuncay | Unknown | Unknown
Since I'm Using Match_Dept_Per Table, If Personel ID isn't Added, I can't do anything.
Any suggestions ?

Use left outer join to include all persons even if they are not associated with the other tables:
select p.id,
p.name,
ifnull(d.name, 'Unknown') DepName,
ifnull(m.workInfo, 'Unknown') workInfo
from personel p
left outer join match_dept_per m
on p.id = m.pers_id
left outer join department d
on d.id = m.dept_id
Here is a demo fiddle.
As you seem to use MS SQL, you might need to use isnull() instead of ifnull(). But I would ommit that anyway because I think it's better to have a NULL in the code where you use the data (Java, C#, whatever). You can control the output there.

Related

SQL to concatenate two columns and join two tables

Table person:
| id | f_name | l_name |
Table sales:
| id | amount | date | itemname |
I have a problem joining the two tables which concat f_name and last_name as fullname column, and joining with table sales. Here id is same on both tables.
Output:
| itemname| date |fullname |
What I have tried:
select *
from
(select
concat(f_name, l_name) as fullname
from
tblperson) p
left join
select itemname, date
from table sales s on s.id = p.id
It should actually be
SELECT table_sales.*, concat(table_person.f_name, table_person.l_name) as fullname
FROM table_person
LEFT JOIN table_sales
ON table_person.id = table_sales.id
have not tested this but that is the syntax
you're missing a field like person_id in your sales table (which references the id field in the person table). You can then use a join to properly join the data together.
You are so close. Try this
select p.*,concat(f_name,l_name)as fullname, s.itemname,s.date, s.amount
from person p left join
sales s on s.id=p.id
Here ia good read on sql join.
https://www.w3schools.com/sql/sql_join.asp

How to resolve an id by an foreign table

I want to resolve an ID by another table, where the name of this id is stored.
SELECT d.id_data, string_agg(s.name_last,', ') AS authors, d.title, i.name
FROM data d, institution i, staffs s
WHERE d.id_staffs = s.id_staffs
AND d.id_institution = i.id_institution
GROUP BY d.id_data limit 100 ;
But how can I get the name of my Institution. I want that the SELECT shows me the institution name, which has stored the data. Something like that
id_data | authors | title | name
----------------------------------------------------------------
1 |Mustermann, Musterfrau | sunmaker | university cologne
2 |Schmidt, Müller | dry age | university berlin
I just need to resolve the id of the institution to his name.
Always use proper, explicit, standard JOIN syntax. Never use commas in the FROM clause.
Presumably, you want something like this:
SELECT d.id_data, string_agg(s.name_last,', ') AS authors,
d.title, i.name
FROM data d JOIN
institution i
ON d.id_staffs = s.id_staffs JOIN
staffs s
ON d.id_institution = i.id_institution
GROUP BY d.id_data, d.title, i.name
LIMIT 100 ;
That is, fix the GROUP BY to have all the unaggregated columns.

Oracle SQL - Return rows with a value based on multiple values in a second field

I need to return the rows that contain the employee names (in one field) who are only classified as Managers (not as Workers, or as Managers and Workers).
Managers and Workers values are in a second field.
So it might look like this:
+----------+------------+
| 'Miller' | 'Manager' |
| 'Jones' | 'Manager' |
| 'Jones' | 'Worker' |
+----------+------------+
In this instance I just want it to return 'Miller'.
I can get one or both, but not the ones where an employee is only classified as a Manager.
Any thoughts?
One method uses aggregation:
select name
from t
group by name
having min(classification) = max(classification) and min(classification) = 'manager';
Count the number of titles. If they have a title of 'Manager' and there's only one title, select the individual:
SELECT *
FROM PEOPLE p
INNER JOIN (SELECT NAME, COUNT(TITLE) AS TITLE_COUNT
FROM PEOPLE
GROUP BY NAME) c
ON c.NAME = p.NAME
WHERE p.TITLE = 'Manager' AND
c.TITLE_COUNT = 1;
dbfiddle here
Method with a subquery which should work well when there are not only 'Managers' and 'Workers' in the table:
SELECT t1.name FROM t t1
WHERE
t1.classification='Manager'
AND NOT EXISTS (
SELECT 1 FROM t t2 WHERE t1.name=t2.name AND t2.classification='Worker'
)

SQL many-to-many JOIN

i am having difficulties joining two tables.
I have the tables
Customer_table
---------------------------------------
| CustomerId(PK) | Firstname | Lastname |
---------------------------------------
CustomerInterest_table
----------------------------------------
| CustomerId(PK,FK) | InterestId(PK,FK) |
----------------------------------------
Interest_table
-------------------------------
| InterestId(PK) | InterestInfo |
-------------------------------
What i want to do is to select every customer, and join the interests with the FK reference on the table.
Ultimately i want to fetch a result containing the customers fetched from the customer table, and the customer interests fetched from the CustomerInterest_table.
Id like to build objects like this
{
customerId : 'Id12345,
firstname : 'John',
lastname : 'Doe',
interests : [{interestId : 1, interestInfo : 'Apples'}]
}
How would i go about fetching and joining the tables ?
Any help greatly appreciated.
Database design (First Normal Form) suppose that column should be simple type, in you case it mean no-array. Instead you can fetch desired from multiple selected rows:
SELECT customerId, firstname, lastname, interestId, InterestInfo
FROM Customer_table c
INNER JOIN CustomerInterest_table tc
ON c.customerId = tc.customerId
INNER JOIN Interest_table i
ON tc.InterestId = i.InterestId
ORDER BY customerId
Last ORDER BY allows you force order of rows so interests of the same customer will follow one by one.
Alternatively if customer MAY not have interests you can leverage LEFT JOIN (then two columns interestId, InterestInfo will be NULL)
SELECT customerId, firstname, lastname, interestId, InterestInfo
FROM Customer_table c
LEFT OUTER JOIN CustomerInterest_table tc
ON c.customerId = tc.customerId
INNER JOIN Interest_table i
ON tc.InterestId = i.InterestId
ORDER BY customerId
UPDATE
Alternatively (if you really want everything in single column for any cost) you can cast result to XML datatype, Then Last column will compose complex XML:
SELECT customerId, firstname, lastname
, [Name]
, (STUFF((SELECT CAST(', ' + interestId AS VARCHAR(MAX) + ':' + InterestInfo)
FROM Interest_table i
WHERE tc.InterestId = i.InterestId
FOR XML PATH ('')), 1, 2, '')) AS interests
FROM Customer_table c
INNER JOIN CustomerInterest_table tc
ON c.customerId = tc.customerId
(p.s. sorry syntax is not checked for correctness)

Oracle SQL join three tables and group by column

I have three tables and I want a query te select teacher names and the number of classes each teacher has reserved.
teacher:
| idt | name |
class:
| idc | name |
reserve:
| idc | idt |
My query:
select
t.name, count(distinct(r.idc))
from
teacher t
join
reserve r
on
r.idt = t.idt
join
class c
on
c.idc = r.idc
group by r.idc
When I run this I get the followin error: not a group by expression.
The group by clause needs to contain all non-aggregated columns from the select statement; in your case it should be t.name. Also, distinct is not a function but a keyword and should not have parentheses.
select
t.name,
count(distinct r.idc) as number_of_classes
from
teacher t
join
reserve r on r.idt = t.idt
join
class c on c.idc = r.idc
group by
t.name