How to get common maximum element from three tables - mysql

I have three tables called table a, table b and table c
all the three tables have one common column.
How to get the common maximum value from the three tables?
here is my table info:
table a
id salary
101 10000
102 15000
103 18000
table b
id salary
110 14000
127 21000
118 15000
table c
id salary
191 15000
192 20000
193 8000
my required output is :
salary
15000

Use UNION ALL (or UNION) to get the salaries of all 3 tables with an extra column, like an id, which marks the source table and then in the HAVING clause of an aggregation query check if that salary belongs to all tables.
Finally use ORDER BY with LIMIT 1 to get the max common salary:
SELECT salary
FROM (
SELECT 1 id, salary FROM tableA UNION ALL
SELECT 2 id, salary FROM tableB UNION ALL
SELECT 3 id, salary FROM tableC
) t
GROUP BY salary
HAVING COUNT(DISTINCT id) = 3 -- get only the common salaries
ORDER BY salary DESC LIMIT 1;

You can use inner joins between the tables to make sure you're only considering values that occur in all three tables.
Then use MAX() to get the greatest of such values.
SELECT MAX(salary) AS salary
FROM tableA JOIN tableB USING (salary) JOIN tableC USING (salary)

Related

Group BY, Average in Group by and individual filtering in SQL

I am not getting the logic of how to do Grouping by the Department and Finding the Average of the Salary of the Department and then filtering all the rows of the table by the values that is greater than Average salary of that department in SQL
Department
Salary
A
100
B
200
A
200
B
50
So avg of group A is 150
and avg of grp B is 125
My query should return :-
Department
Salary
B
200
A
200
You should please have a look how grouping works in SQL. This query will find the department and its average salary:
SELECT department, AVG(salary) salary FROM yourtable
GROUP BY department;
In order to find the departments having a higher salary, you can just join the whole table and this "average result" and choose those entries only that have a higher salary:
SELECT y.department, y.salary FROM yourtable y
JOIN (SELECT department, AVG(salary) salary FROM yourtable
GROUP BY department) average
ON y.department = average.department
WHERE y.salary > average.salary
ORDER BY y.department;
The order clause let department A appear before department B. In your description, it's sorted the other way. If you want to change this, you can write ORDER BY y.department DESC;
A last note: If there are NULL values in the salary table, they will note be considered by the average function. So if you have 10 null values, one row with a salary of 100 and one with a salary of 50, the average will be 75 and "ignore" the NULL values. If you don't want this, you need to replace the NULL values by the value you want. As example, you could write COALESCE(salary,0) within your query if you want to replace all NULL values by zero when calculating your average salary.

Aggregated row count differences between tables

I have two MySQL tables A and B both with this schema
ID
entity_id
asset
asset_type
0
12345
x
1
..
.........
.....
..........
I would like to get an aggregated top 10/50/whatever entity_ids with the largest row count difference between the two tables. I think I could do this manually by just getting the highest row count by entity_id like so
select count(*), entity_id
-> from A
-> group by entity_id
-> order by count(*) desc;
and just manually comparing to the same query for table B but I'm wondering if there's a way to do this in just one query, that compares row counts for each distinct entity_id and aggregates the differences between row counts. A few notes
There is an index on entity_id for both tables
Table B will always have an equivalent or greater number of rows for each entity_id
Sample output
entity_id
difference
12345
100
3232
75
5992
40
and so on
for top 10/50
Aggregate in each table and join the results to get the difference:
SELECT a.entity_id, b.counter - a.counter diff
FROM (SELECT entity_id, COUNT(*) counter FROM A GROUP BY entity_id) a
INNER JOIN (SELECT entity_id, COUNT(*) counter FROM B GROUP BY entity_id) b
ON a.entity_id = b.entity_id
ORDER BY diff DESC LIMIT 10

Query BETWEEN TWO TABLES OUTPUT (MYSQL)

two table EMPLOYEE and Department
EMPLOYEE's fields are ID,Name, Salary ,DEPT_ID(foreign key to department table)
DEPARTMENT'S fields are id,NAME,LOCATION
VALUES OF EMPLOYEE TABLE WILL Be
Values OF DEPARTMENT TABLE WILL BE
Output from these table should be
DEPARTMENT_Name should be alpabetically within their count If are there same Count DEPARTMENT_Name should appear in alpabetically and count will be desc order
EMPLOYEE TABLE Values
id name salary dept_id
1 Candice 4685 1
2 Julia 2559 2
3 Bob 4405 4
4 Scarlet 2305 1
5 Ileana 1151 4
Department TABLE Values
id name location
1 Executive Sydney
2 Production Sydney
3 Resources Cape Town
4 Technical Texas
5 Management Paris
OUTPUT DATA SHOULD BE
DEPARTMENT_Name Count_OF_EMPLOYEE_SAME_DEPARTMENT
Executive 2,
Technical 2,
PRODUCTION 1,
MANAGEMENT 0,
RESOURCES 0
For what you want to show all departments even if there are no employees is a LEFT JOIN. So, start with the department table (alias "d" in the query) and LEFT JOIN to the employee table (alias "e"). using shorter alias names that make sense with context makes readability easier.
Now, you have the common "count()" which just returns a count for however many records are encountered, even if multiple in the secondary (employee) table based on common ID. In addition to count(), I also did a sum of the employee salary just for purposes that you can get multiple aggregate values in the same query.. Use it or don't, just wanted to present as an option for you.
Now the order. You want that based on the highest count first, so the COUNT(*) DESC (descending order) is the first sorting. Secondary is the department name to keep alphabetized if within the same count.
select
d.`name` Department_Name,
d.Location,
count(*) NumberOfEmployees,
sum( coalesce( e.salary, 0 )) as DeptTotalSalary
from
Department d
left join employee e
on d.dept_id = e.id
group by
d.`name`
order by
count(*) desc,
d.`name`

Not able to understand the query

I wanted to find two maximum salaries from every department in a table which had department no., salary, and various other columns. I got this answer; it surely works but I am not able to understand the logic.
select *
from emp a where 2 > (select count( distinct(sal))
from emp
where sal > a.sal and a.deptno=deptno)
order by deptno;
For each row in employee, the query within the WHERE clause counts how many rows have a higher salary in the same department. The WHERE clause itself then restricts the results to only those salaries which have 1 or 0 rows (2 >) in the same department with a greater salary - i.e. the highest two salaries.
So with this data:
EmployeeId Sal DeptNo No. of rows in the same department with higher salary
1 1 1 3 (employees 2, 3 and 4)
2 2 1 2 (employees 3 and 4)
3 3 1 1 (employee 4)
4 4 1 0
5 1 2 2 (employees 6 and 7)
6 2 2 1 (employee 7)
7 3 2 0
...the query will select employees 3, 4, 6 and 7, as they're the employees with fewer than 2 employees who have a higher salary than them.
The inner select returns the number of higher salaries within the same department for a given employee. Now if there are less than two higher salaries within the same department then the given employee must be the top earning or next-to-top earning person within the department.
Relocate the subquery to the SELECT clause without the 'top 2' restriction (will obviously get more rows back):
select a.*,
(
select count( distinct(sal))
from emp
where sal > a.sal and a.deptno=deptno
) as tally
from emp a
You can then restrict the resultset using a WHERE clause introducing a further level e.g.
select b.*
from (
select a.*,
(
select count( distinct(sal))
from emp
where sal > a.sal and a.deptno=deptno
) as tally
from emp a
) b
where b.tally < 2
order
by b.deptno, b.tally;
The above is more verbose but maybe easier to follow the logic.

mysql count unique row values

TABLE quotation
id clientid
1 25
2 25
3 25
4 25
5 26
How can I query how many different clients exist in TABLE quotation? I don't want duplicate entries to be counted more than once.
I need the answer to be 2, in 1 row, because the only non-duplicated entries are (25, 26).
select count(distinct clientid) from quotation
read more
I find a way out
SELECT COUNT(*) as total FROM (SELECT COUNT(*) FROM quotation GROUP BY
clientid) t1
If you want to count the total number of unique entries this will return a number in column count.
SELECT COUNT(*) as total FROM (SELECT COUNT(*) FROM quotation GROUP BY clientid having count(*) > 1) t1
If you want to count the total number of entries with duplicate rows then use the following mysql.
SELECT COUNT(*) as total FROM (SELECT COUNT(*) FROM quotation GROUP BY clientid having count(*) >= 2) t1
I tried the following on a MySQL 5.x database.
id is an integer and clientid is an integer. I populated with two rows:
id clientid
1 25
2 25
This SQL query will print the rows that have exactly 2 elements:
select * from test1 group by clientid having count(*) = 2;
If you want 2 or more elements, replace = 2 in the example above with >= 2.
select * from test1 group by clientid having count(*) >= 2;
SELECT clientid, COUNT(clientid) FROM quotation
GROUP BY clientid