Join two tables with Mapping and get result - mysql

I'm use HBase DB with phoenix, I have 3 tables in which two are Main table which have many to many relation ship between them which is mapped by the third table.
Employee
EmpID EmpName
1 Robert
2 John
3 Sansa
4 Ned
5 Tyrion
6 George
7 Daenerys
8 Arya
9 Cersie
10 Catelyn
Department
DepID DepName
1 Hardware
2 Software
3 Admin
4 HR
Department_Employee_Mapping
ID DepID EmpID
1 1 2
2 1 6
3 2 1
4 3 5
5 3 6
6 4 3
7 4 7
8 4 10
9 4 5
I want to get names and department of all the employees who are in Admin Department, but also I want the details of those employee who belong to other department and who do not belong to any of the departments and these data should appear as NULL in the resultset Only the value for admin department should appear and if the employee belong to multiple departments, the result set should contain the value the Admin department and the other one will be ignored, Result set will look like
Emp Name Dep Name
Robert NULL
John NULL
Sansa NULL
Ned NULL
Tyrion Admin
George Admin
Daenerys NULL
Arya NULL
Cersie NULL
Catelyn Admin

Use 2 LEFT JOIN and include the filtering on 'Admin' in the join against Department
SELECT DISTINCT e.empname, d.depname
FROM Employee e
LEFT JOIN Department_Employee_Mapping x ON x.empid = e.id
LEFT JOIN Departmentd ON d.id = x.depid AND d.id = 3

Related

MySQL join based on where from 2nd table

I have two tables as follows:
docs
id
carid
name
1
1
doc1
2
1
doc2
3
2
doc3
4
1
doc4
5
5
doc5
cars
carid
parentid
name
1
4
car1
2
5
car2
3
4
car3
4
4
car4
5
5
car5
Question: I want to write a query in mysql where I can pass the carid in where clause and get all the rows from docs table where the parentid is same as that of the passed carid.
Desired Outcome If I pass carid=3 then the rows 1,2,4 from docs table should be returned as the parentid is 4 for carids 1,3,4.
Simillarly, If I pass carid=2 then the rows 3,5 from docs table should be returned as the parentid is 5 for carids 2.5.
You need to join the cars-table twice. First for the condition and second for the parent:
select d.*
from cars c
join cars p on p.parentid=c.parentid
join docs d on d.carid=p.carid
where c.carid=3
You're thinking about this a little wrong in the aspect of a relational database .. You SHOULD have 4 tables:
docs
doc_id
name
1
doc1
2
doc2
3
doc3
4
doc4
5
doc5
cars
car_id
name
1
car1
2
car2
3
car3
4
car4
5
car5
cars_to_docs
car_id
doc_id
1
1
1
2
1
4
2
3
5
5
parents_to_car
car_id
parent_id
1
4
2
5
3
4
4
4
5
5
Then you could simply use a basic JOIN
SELECT b.doc_id FROM test.docs a
LEFT JOIN test.cars_to_docs b
ON a.doc_id = b.car_id
LEFT JOIN test.parents_to_car c
ON c.car_id = b.car_id
LEFT JOIN test.cars d
ON c.car_id = d.car_id
WHERE c.parent_id = (SELECT parent_id FROM test.parents_to_car WHERE car_id = 3)
This will give you your output of 1,2,4

Putting a table result as a text column

I have two tables, the first one is a table of companies, and the second one is a table of shareholders we could say. The shareholder table can have upwards of a thousand shareholders.
I need to make a view/another table which has every shareholder name on a single text column along with the unique identifier of the company, the name and "fake" name of the company.
Table 1 Company:
ID CompanyID Name FantasyName
1 1 A Company 1
2 2 B Company 2
3 3 C Company 3
4 4 D Company 4
5 5 E Company 5
6 6 F Company 6
7 7 G Company 7
Table 2 Shareholders:
ID CompanyID Name
1 1 John 1
2 1 Peter 2
3 1 Gabriel Li
4 2 Raphael 3
5 2 Anderson 4
6 2 Michael 6
7 2 Angelina Jo
8 3 John 8
9 4 Beatrice
10 4 Scarlet
11 5 Scarlet
12 5 Logan
13 5 John 1
I tried to do this via Linq through C# but it hasn't been fast enough for my purpose, this table contains upwards of millions of companies.
The end result would look like this:
Table 3 Company and Shareholders:
ID CompanyID Name FantasyName Shareholders
1 1 A Company 1 John 1,Peter 2,Gabriel Li
2 2 B Company 2 Raphael 3, Anderson 4,Michael 6,Angelina Jo
3 3 C Company 3 John 8
4 4 D Company 4 Beatrice,Scarlet
5 5 E Company 5 Scarlet,Logan,John 1
...
All shareholders in a single TEXT field, with the company info accompanying it.
You can use aggregation and GROUP_CONCAT():
CREATE VIEW myview AS
SELECT
c.ID,
c.CompanyID,
c.Name,
c.FantasyName,
GROUP_CONCAT(s.Name) Shareholders
FROM
Company c
INNER JOIN Shareholders s ON s.CompanyID = c.CompanyID
GROUP BY
c.ID,
c.CompanyID,
c.Name,
c.FantasyName

SQL query that finds all the column, that is in multiple rows, but have different value in another column?

If I have a "SALES" table, with columns of SaleID, Product#, and CustomerName. and a PRODUCTS table with two columns product_ID and Name. The contains 5 differnt products. In the SALES table populates when a sale is made.
How would I query customer_name with only Product_ID of 1 and 2?
sales table
SALES_ID PRODUCT_ID CUSTOMER_NAME
1 1 DAVE
2 2 DAVE
3 3 DAVE
4 1 TOM
5 2 TOM
6 1 JANE
7 1 MIKE
8 1 MIKE
9 3 MIKE
10 4 MARY
I would like a table result to be
SALES_ID PRODUCT_ID CUSTOMER_NAME
1 1 TOM
2 2 TOM
Select s.CustomerName from SALES s
INNER JOIN PRODUCTS p ON s.Product#=p.Product#
WHERE p.Product# =1
INTERSECT
Select s.CustomerName from SALES s
INNER JOIN PRODUCTS p ON s.Product#=p.Product#
WHERE p.Product# =2

Is it possible write this query without cursor

I am using mysql database
The schema of department is
Department Table
Deptid DeptName
1 CEO
2 HR
3 IT
4 Dev
5 QA
Employee table
Empid EmpName managerid deptid
1 E1 1
2 E2 1 2
3 E3 1 3
4 E4 3 4
5 E5 4 4
6 E6 4 4
7 E7 3 5
8 E8 7 5
9 E9 7 5
I need output as
deptid parentdept count
1 1
2 1 1
3 1 1
4 3 3
5 3 3
Parent department is department which belongs to manager of employee.
It means It department CEO is parent department of IT and HR because IT and HR managers report to CEO dept manager.
It means It department IT is parent department of Dev and QA because DEV and QA managers report to IT dept manager.
deptid parentdept count
CEO 1
HR CEO 1
IT CEO 1
DEV IT 3
QA IT 3
Tree representation of it is
CEO-(deptid 1)E1
HR-(deptid 2)E2 IT-(deptid 3)E3
DEV-(deptid 4)E4 QA(deptid 5)E7
E5-(deptid 4) E6-(deptid 4) E8-(deptid 5) E9-(deptid 5)
I thought the managerid shoudn't be equal to the any empid in the same department rows by your descriptions.
select A.deptid,B.parentdept,A.count from (select deptid,
count(*) as count from Employee group by deptid) as A
left join
(select t1.deptid, t3.deptid as parentdept from Employee t1,Employee t3 where t1.managerid not
in (select Empid from Employee t2 where t2.deptid=t1.deptid)
and t1.managerid=t3.empid) as B
on A.deptid=B.deptid;
if I missed something in the logic, apologies in advance.

Retrieve from multiple tables while only allowing distinct results for one column

I am trying to select from three tables, Regions, Players, and regionplayer. and order the results by region name, and then by when the players attached to that region where last seen. I would really like it so that i only return one result for each region, with the player who hasn't been seen the longest.
SQL.
SELECT RegionName.*, RegionPlayer.*, Players.*
FROM RegionName
JOIN RegionPlayer
ON RegionPlayer.Regionkey = RegionName.Key
JOIN Players
ON Players.Key = RegionPlayer.Playerkey
GROUP BY RegionName.Name, Players.Seen DESC
some table data.
RegionName
key Name
1 regionone
2 regiontwo
3 regionthree
4 regionfouor
5 regionfive
Players
Key Name Seen
1 jack 2014-03-21 12:43:46
2 joe 2014-03-26 12:43:46
3 bob 2014-03-20 12:43:46
4 bill 2014-03-19 12:43:46
5 dave 2014-03-17 12:43:46
6 tina 2014-03-28 12:43:46
7 tony 2014-03-29 12:43:46
8 george 2014-03-15 12:43:46
9 sam 2014-03-18 12:43:46
10 frank 2014-03-18 12:43:46
RegionPlayer
key Regionkey PlayerKey
1 1 1
2 1 4
3 1 5
4 2 1
5 2 4
6 3 6
7 3 7
8 4 1
9 4 8
10 4 7
11 5 3
I take your statement, at first the part before GROUP BY
SELECT RegionName.*, RegionPlayer.*, Players.*
FROM RegionName
JOIN RegionPlayer
ON RegionPlayer.Regionkey = RegionName.Key
JOIN Players
ON Players.Key = RegionPlayer.Playerkey
and add
WHERE Players.Seen = (
SELECT MIN(Players2.Seen)
FROM RegionName as RegionName2
JOIN RegionPlayer as RegionPlayer2
ON RegionPlayer2.Regionkey = RegionName2.Key
JOIN Players as Players2
ON Players2.Key = RegionPlayer2.Playerkey
WHERE RegionName2.Key = RegionName.Key
)
and then GROUP BY from your statement
GROUP BY RegionName.Name, Players.Seen DESC
The subselect returns the minimum date SEEN from PLAYERS for current region.