Unusual two tables join - sql

I have table Persons:
----------------------------------------
id | name | phone | house_id |
----------------------------------------
1 | Sarah | 1234567 | 101 |
2 | Joseph | 7654321 | 102 |
3 | David | 1231231 | null |
Ans second table Houses:
----------------------------------------
id | street | number |
----------------------------------------
101 | Evergreen Terrace | 742 |
102 | Baker Street | 223B |
103 | Oxford Street | 23A |
I need such output table as following:
--------------------------------------------------------------------------------
id(person)| name | phone | house_id | id(house) | street | number |
--------------------------------------------------------------------------------
1 | Sarah | 1234567 | 101 | 101 | Evergreen T...| 742 |
2 | Joseph | 7654321 | 102 | 102 | Baker Street | 223B |
3 | David | 1231231 | null | null | null | null |
4 | null | null | null | 103 | Oxford Street | 23A |
What kind of join do I need to use to achieve such result?

SELECT
A.id AS 'Person',
A.name,
A.phone,
A.house_id,
B.id AS 'House',
B.street,
B.number
FROM
Persons AS A
FULL OUTER JOIN Houses AS B
ON A.house_id = B.id

Related

match TableA.Id with TableB.Id Than return TableB.Country

I have two tables in my SQLite databaselike this
Table A:
| Id | Date | Rate | Person
|:-- |:-------:| ----:| ------:|
| 1 | 2022-02 | 6.3 | Alex |
| 1 | 2022-05 | 4.2 | John |
| 2 | 2022-09 | 2.5 | Alex |
| 3 | 2022-01 | 7.8 | David |
| 2 | 2022-21 | 9 | William|
Table B:
| Id | City | Country |
|:-- |:---------:| -------:|
| 1 | London | England |
| 2 | Paris | France |
| 3 | Washington| USA |
| 4 | Berlin | Germany |
I need a query to get Id and Rate of each row, in table A then get Country of that Id in Table B
The result should be something like this
Table C:
| Ids | Countries | Rates |
|:--- |:---------:| -----:|
| 1 | England | 6.3 |
| 1 | England | 4.2 |
| 2 | France | 2.5 |
| 3 | USA | 7.8 |
| 2 | France | 9 |
You need to join A and B with Id, and select some columns:
select B.Id as Ids,
B.Country as Countries,
A.Rate as Rates
From A inner join B on(A.Id = B.Id)

Get hierarchy of all different level of managers

I'm using pgAdmin4 and I have a SQL table with employee/manager HR data that looks like this:
| employee_id | email_address | full_name | band_lvl | manager_id |
| 5592 | jillr#ex.org | Jill Rhode | 20 | 6521 |
| 6421 | racheln#ex.org | Rachel Nam | 40 | 4251 |
| 2818 | todda#ex.org | Todd Alex | 25 | 6421 |
| 4251 | jalens#ex.org | Jalen Smith | 60 | 2199 |
| 6521 | tolun#ex.org | Tolu Nagoye | 30 | 2199 |
| 7831 | jina#ex.org | Ji Na | 80 | NULL |
| 2199 | zaynm#ex.org | Zayn Mate | 70 | 7831 |
Based on the first manager_id and employee_id, I'm seeking to return the following columns: Level1 Manager Name, Level1 Manager Email, Level1 Manager Band Lvl, Level1 Manager Manager's Id. I then want to do that for each manager that's a step above, until there are no higher managers.
The desired output should look like this:
| employee_id | email_address | full_name | band_lvl | manager_id | Lvl1 Mng Nm | Lvl1 Mng Email | Lvl1 Mng Band Lvl | Lvl1 Mng Mngs Id | Lvl2 Mng Nm | Lvl2 Mng Email | Lvl2 Mng Band Lvl | Lvl2 Mng Mngs Id |
| 5592 | jillr#ex.org | Jill Rhode | 20 | 6521 | Tolu Nagoye | tolun#ex.org | 30 | 2199 | Zayn Mate | zaynm#ex.org | 70 | 7831 |
| 6421 | racheln#ex.org | Rachel Nam | 40 | 4251 | Jalen Smith | jalens#ex.org | 60 | 2199 | Zayn Mate | zaynm#ex.org | 70 | 7831 |
| 2818 | todda#ex.org | Todd Alex | 25 | 6421 | Rachel Nam | racheln#ex.org | 40 | 4251 | Jalen Smith | jalens#ex.org | 60 | 2199 |
| 4251 | jalens#ex.org | Jalen Smith | 60 | 2199 | Zayn Mate | zaynm#ex.org | 70 | 7831 | Ji Na | jina#ex.org | 80 | NULL |
| 6521 | tolun#ex.org | Tolu Nagoye | 30 | 2199 | Zayn Mate | zaynm#ex.org | 70 | 7831 | Ji Na | jina#ex.org | 80 | NULL |
| 7831 | jina#ex.org | Ji Na | 80 | NULL | NULL | NULL | NULL | NULL | NULL | NULL | NULL | NULL |
| 2199 | zaynm#ex.org | Zayn Mate | 70 | 7831 | Ji Na | jina#ex.org | 80 | NULL | NULL | NULL | NULL | NULL |
So far, this is what I've come up with, to get the first columns for the Level 1 Manager; however, I don't know where to go from here, as I'm very new to SQL:
SELECT B.employee_id,
B.email_address,
B.full_name,
B.band_lvl,
B.manager_id,
B1.full_name AS L1_mng_nm,
B1.email_address AS L1_mng_email,
B1.band_lvl AS L1_mng_band_lvl,
B1.manager_id AS L1_mgr_mgrs_id
FROM hrdata B
INNER JOIN hrdata B1 ON
B.manager_id = B1.employee_id;
Your query is close, but you would need to make a few changes to get to your desired output. To begin, I would recommend doing a LEFT JOIN as opposed to an INNER JOIN, as the INNER JOIN will not return null values and will instead drop records that it cannot find a match for in both tables (in this case, if it cannot find a match on manager_id to employee_id from the first use of hrdata to the second use of hrdata).
After that, your query should look similar to what you have already done, just with another self-join to get the second-level manager data:
SELECT B.employee_id,
B.email_address,
B.full_name,
B.band_lvl,
B.manager_id,
B1.full_name AS L1_mng_nm,
B1.email_address AS L1_mng_email,
B1.band_lvl AS L1_mng_band_lvl,
B1.manager_id AS L1_mgr_mgrs_id,
B2.full_name AS L2_mng_nm,
B2.email_address AS L2_mng_email,
B2.band_lvl AS L2_mng_band_lvl,
B2.manager_id AS L2_mgr_mgrs_id,
FROM hrdata B
LEFT JOIN hrdata B1
ON B1.employee_id = B.manager_id
LEFT JOIN hrdata B2
ON B2.employee_id = B1.manager_id

How to count and summarize rows in two or more separate tables

as following, I have two tables in SQL like below:
Request Table:
+------------+------------+--------+
| #technician| #RequestID | #title |
+------------+------------+--------+
| emma james | 1121 | title10|
+------------+------------+--------+
| emma james | 2155 | title11|
+------------+------------+--------+
| emma james | 8787 | title12|
+------------+------------+--------+
| john roody | 9584 | title13|
+------------+------------+--------+
| john roody | 8744 | title14|
+------------+------------+--------+
| scott olga | 1556 | title15|
+------------+------------+--------+
| tom jonas | 9941 | title16|
+------------+------------+--------+
Task Table:
+-------------+---------+---------+
| #owner | #taskID | #title |
+-------------+---------+---------+
| emma james | 232 | title0 |
+-------------+---------+---------+
| emma james | 945 | title1 |
+-------------+---------+---------+
| tom jonas | 542 | title2 |
+-------------+---------+---------+
| tom jonas | 887 | title3 |
+-------------+---------+---------+
| tom jonas | 215 | title4 |
+-------------+---------+---------+
| john roody | 268 | title5 |
+-------------+---------+---------+
| scott olga | 258 | title6 |
+-------------+---------+---------+
how can we summarize the count of Appearance for each technician name in a separate table by Query like this:
+------------+-----------------+--------------+-------------+
| #Name | #RequestIDcount | #TaskIDcount | #TotalCount |
+------------+-----------------+--------------+-------------+
| emma james | 3 | 2 | 5 |
+------------+-----------------+--------------+-------------+
| tom jonas | 1 | 3 | 4 |
+------------+-----------------+--------------+-------------+
| john roody | 2 | 1 | 3 |
+------------+-----------------+--------------+-------------+
| scott olga | 1 | 1 | 2 |
+------------+-----------------+--------------+-------------+
One method is union all and aggregation:
select name,
sum(is_request) as num_requests, sum(is_task) as num_tasks,
(sum(is_request) + sum(is_task)) as total
from ((select technician as name, 1 as is_request, 0 as is_task
from requests
) union all
(select owner, 0, 1
from tasks
)
) rt
group by name;
There are several ways, here's one using FULL OUTER JOIN
SELECT
ISNULL(r.name, t.name) AS name,
ISNULL(r.num_r, 0) AS num_requests,
ISNULL(t.num_t, 0) AS num_tasks,
ISNULL(r.num_r, 0) + ISNULL(t.num_t, 0) AS total
FROM
(SELECT technician AS name, COUNT(*) AS num_r FROM requests GROUP BY 1) AS r
FULL OUTER JOIN
(SELECT owner AS name, COUNT(*) AS num_t FROM tasks GROUP BY 1) AS t
ON r.name = t.name
If you know that every name always has at least one record in both tables, you don't need the ISNULL() and can use INNER JOIN instead.

Display the sale id and sale date of sales made by salesmen working from London

I have three tables:
Salesman Table
+-----+---------+----------+
| SID | SNAME | LOCATION |
+-----+---------+----------+
| 1 | Peter | London |
| 2 | Michael | Paris |
| 3 | John | Mumbai |
| 4 | Harry | Chicago |
| 5 | Kevin | London |
| 6 | Alex | Chicago |
+-----+---------+----------+
Sale Table
+--------+-----+-----------+
| SALEID | SID | SLDATE |
+--------+-----+-----------+
| 1001 | 1 | 01-JAN-14 |
| 1002 | 5 | 02-JAN-14 |
| 1003 | 4 | 01-FEB-14 |
| 1004 | 1 | 01-MAR-14 |
| 1005 | 2 | 01-FEB-14 |
| 1006 | 1 | 01-JUN-15 |
+--------+-----+-----------+
Expected Result
+--------+-----------+
| SALEID | SLDATE |
+--------+-----------+
| 1001 | 01-JAN-14 |
| 1002 | 02-JAN-14 |
| 1004 | 01-MAR-14 |
| 1006 | 01-JUN-15 |
+--------+-----------+
I am using Oracle SQLDeveloper. I run the code below:
SELECT S.SALEID, S.SLDATE
FROM Salesman SA
INNER JOIN Sale S ON SA.SID = S.SID
WHERE SA.LOCATION = 'London';
but I get error:
Error: Your result did not match the Expected result.
If anyone can find the errors please answer.
OKAY, I got it, it was an database error, Refreshed the database and the same Query worked.
The query mentioned is correct tho.

group by SQL properly

I have a table that stores the names and values on separate rows for work that takes place on a location like this below.
+--------+------------+--------+------------+----------+
| WorkID | Attribute | Value | Chagedby | Date |
+--------+------------+--------+------------+----------+
| 1 | Unit Name | Unit 1 | John Smith | Jan-2018 |
| 1 | Unit Value | OK | John Smith | Jan-2018 |
| 2 | Unit Name | Unit 2 | John Smith | Feb-2018 |
| 2 | Unit Value | Not Ok | John Smith | Feb-2018 |
| 3 | Unit Name | Unit 3 | John Smith | Mar-2018 |
| 3 | Unit Value | OK | John Smith | Mar-2018 |
+--------+------------+--------+------------+----------+
I have a query on this table that joins other tables and the output looks like this.
+--------+--------------+--------------------+----------------------+------------+----------+
| WorkID | Location | Value when unit ID | Value when ok/not ok | Chagedby | Date |
+--------+--------------+--------------------+----------------------+------------+----------+
| 1 | Springfield | Unit 1 | NULL | John Smith | Jan-2018 |
| 1 | Springfield | NULL | OK | John Smith | Jan-2018 |
| 2 | Shelbyville | Unit 2 | NULL | John Smith | Feb-2018 |
| 2 | Shelbyville | NULL | Not Ok | John Smith | Feb-2018 |
| 3 | Capital City | Unit 3 | NULL | John Smith | Mar-2018 |
| 3 | Capital City | NULL | OK | John Smith | Mar-2018 |
+--------+--------------+--------------------+----------------------+------------+----------+
what ends up happneing is the attribute "Value" is either the Name of my unit or the result of the test. how do i group this so it shows up on the same line.
+--------+--------------+--------------------+----------------------+------------+----------+
| WorkID | Location | Value when unit ID | Value when ok/not ok | Chagedby | Date |
+--------+--------------+--------------------+----------------------+------------+----------+
| 1 | Springfield | Unit 1 | OK | John Smith | Jan-2018 |
| 2 | Shelbyville | Unit 2 | Not OK | John Smith | Feb-2018 |
| 3 | Capital City | Unit 3 | OK | John Smith | Mar-2018 |
+--------+--------------+--------------------+----------------------+------------+----------+
I would join the table to itself, filtering once by name, the other one by value, as in:
select
a.workid,
a.value as name,
v.value as value,
a.changedby,
a.date
from my_table a
left join my_table v on a.workid = v.workid
where a.attribute = 'Unit Name'
and v.attribute = 'Unit Value'
I added a left join to include attributes that don't have a value yet.