Divide count by average in SQL from three different tables - mysql

I have three tables and I am using counts from each tables to get a rate%.
This is the formula and I am trying to replicate it using MySQL
Count1.t1/AVERAGE(Count2.t2,Count3t.3)
So far the average is working and this is what I have:
This code block gives me the average between t1 and t2.
SELECT AVG(ID.TAvg) FROM ( select count(*) as TAvg from t2 UNION Select count(*) as TAvg from t3) ID;
However, if I divide t1 count with the average it breaks.
(SELECT COUNT(ID) from t1) / (SELECT AVG(ID.TAvg) FROM ( select count(*) as TAvg from t2 UNION Select count(*) as TAvg from t3) ID);
Can anyone please help with this? I am basically trying to get a count from one table and divide it with an average from two separate tables. I appreciate the help.

Your:
(SELECT COUNT(ID) from t1) / (SELECT AVG(ID.TAvg) FROM ( select count(*) as TAvg from t2 UNION Select count(*) as TAvg from t3) ID)
is the value you want, but it is an expression, not a select. You can just add a select:
SELECT (SELECT COUNT(ID) from t1) / (SELECT AVG(ID.TAvg) FROM ( select count(*) as TAvg from t2 UNION Select count(*) as TAvg from t3) ID)
or do the divide in the from t1:
SELECT COUNT(ID) / (SELECT AVG(ID.TAvg) FROM ( select count(*) as TAvg from t2 UNION Select count(*) as TAvg from t3) ID) from t1
(Though you don't say what "it breaks" actually means; do you in fact have an ID column in t1 and want to count rows where ID is not null? If you just want to count all rows in t1, do count(*) or count(1), not count(ID).)
One other thing: UNION means UNION DISTINCT, which removes duplicate rows after unioning (as opposed to UNION ALL which just unions the rows from the two queries). Since you are just averaging two tables, there is no problem, but if you were summing, or averaging three tables, there would be. For instance, if you were averaging 3, 3, and 6, with UNION ALL, that would produce 4, but with UNION DISTINCT, it first becomes just 3 and 6, producing an average of 4.5. You almost always want to say UNION ALL, not just UNION.

Related

How I create a view with the record count of different tables

I need to create a view with the record count from 3 different tables but with the same columns.
That is, these queries
SELECT COUNT (*) AS count_a from table1 ta
SELECT COUNT (*) AS count_b from table2 tb
SELECT COUNT (*) AS count_c from table3 tc
Introduced in a view, the join can be a solution but I think this would take a lot of work, and likewise being a different count in each table, when using join it would discard some, if in a table there are 100, 200, 15. No I know if the join would be the solution to this.
I wanted to use the GROUP_CONCAT but reviewing a bit does not seem to be a solution, anyway. In simple words I want the count of different tables in a view so that it is displayed
Desired result
count_a
count_b
count_c
100
200
15
Greetings and thanks in advance
PS: right now I do not remember well how the JOIN works
If you want to display only the result of these 3 counts, without any join between tables. I suggest to use a script like this :
create view desired_result
as select * from (
(SELECT COUNT(*) AS count_a from table1) t1,
(SELECT COUNT(*) AS count_b from table2) t2,
(SELECT COUNT(*) AS count_c from table3) t3);
You can try it with this fiddle link
try a query like this:
SELECT
(SELECT count(*) FROM table1) AS count_a,
(SELECT count(*) FROM table2) AS count_b,
(SELECT count(*) FROM table3) AS count_c;
If you like without JOIN:
SELECT
(SELECT count(*) as count_a FROM table1) AS count_a,
(SELECT count(*) as count_b FROM table2) AS count_b,
(SELECT count(*) as count_c FROM table3) AS count_c;
If you like with JOIN:
SELECT ta.count_a, tb.count_b, tc.count_c FROM
(
SELECT COUNT (*) AS count_a, 1 AS rn from table1) ta
JOIN (
SELECT COUNT (*) AS count_b, 1 AS rn from table2) tb
ON ta.rn = tb.rn
JOIN (
SELECT COUNT (*) AS count_c, 1 AS rn from table3) tc
ON ta.rn = tc.rn

using count and sum in different tables [duplicate]

How do I go about selecting COUNT(*)s from multiple tables in MySQL?
Such as:
SELECT COUNT(*) AS table1Count FROM table1 WHERE someCondition
JOIN??
SELECT COUNT(*) AS table2Count FROM table2 WHERE someCondition
CROSS JOIN? subqueries?
SELECT COUNT(*) AS table3Count FROM table3 WHERE someCondition
Edit:
The goal is to return this:
+-------------+-------------+-------------+
| table1Count | table2Count | table3Count |
+-------------+-------------+-------------+
| 14 | 27 | 0 |
+-------------+-------------+-------------+
You can do it by using subqueries, one subquery for each tableCount :
SELECT
(SELECT COUNT(*) FROM table1 WHERE someCondition) as table1Count,
(SELECT COUNT(*) FROM table2 WHERE someCondition) as table2Count,
(SELECT COUNT(*) FROM table3 WHERE someCondition) as table3Count
You can do this with subqueries, e.g.:
select (SELECT COUNT(*) FROM table1 WHERE someCondition) as table1Count,
(SELECT COUNT(*) FROM table2 WHERE someCondition) as table2Count
Here is simple approach to get purely the row counts from multiple tables, if there are no conditions on specific tables.
Note:
For InnoDB this count is an approximation. However, for MyISAM the count is accurate.
Quoted from the docs:
The number of rows. Some storage engines, such as MyISAM, store the
exact count. For other storage engines, such as InnoDB, this value is
an approximation, and may vary from the actual value by as much as 40%
to 50%. In such cases, use SELECT COUNT(*) to obtain an accurate
count.
Using the information_schema.tables table you can use:
SELECT
table_name,
table_rows
FROM
information_schema.tables
WHERE
table_name like 'my_table%';
Output:
table_name table_rows
my_table_1 0
my_table_2 15
my_table_3 30
You can use UNION
SELECT COUNT(*) FROM table1 WHERE someCondition
UNION
SELECT COUNT(*) FROM table2 WHERE someCondition
UNION
SELECT COUNT(*) FROM table3 WHERE someCondition
You can do this in this way.
SELECT (select count(*) from table1) + (select count(*) from table2) as total_rows
You can add as many tables as you want.
Try changing to:
SELECT
COUNT(table1.*) as t1,
COUNT(table2.*) as t2,
COUNT(table3.*) as t3
FROM table1
LEFT JOIN tabel2 ON condition
LEFT JOIN tabel3 ON condition
Not directly, but it works...
1.- Create a list of the tables you need to count rows.
2.- Put that list in the first column of a spreadsheet.
3.- In the second column, first row, use this formula:
="SELECT '"&A1&"', (SELECT count(*) FROM "&A1&") UNION"
4.- Fill down the formula.
5.- Copy the second column and paste it to do the query.
6.- Don't forget to remove the last UNION.

SQL - Order By Sum of Multiple Tables Sharing Common Field

I have 2 different tables sharing the same column names. The tables list the same products which are identified by 'id'. The products have different revenues throughout both tables and are listed multiple times in each table.
I would like to sum the revenue of the same products across the 2 tables and ORDER BY the sum. Result is sorting the highest revenue products first.
I've tried JOIN and UNION but can't seem to figure out the right solution.
UNION query I tried...
SELECT id, SUM(rev) as total
FROM (
SELECT id, rev FROM table1 UNION ALL
SELECT id, rev FROM table2 UNION ALL
)
ORDER BY total DESC
JOIN query I tried...
SELECT table1.id,
table1.rev,
table2.id,
table2.rev,
(table1.rev + table2.rev) as revenue
FROM table1
INNER JOIN table2 ON table1.id = table2.id
ORDER BY revenue DESC
You were close. You needed:
one UNION ALL, not two.
a GROUP BY, that gives the break field.
An alias for the subquery (I used AllRevenue - you can use any valid name.)
SELECT id, SUM(rev) as total
FROM (
SELECT id, rev FROM table1 UNION ALL
SELECT id, rev FROM table2
) AS AllRevenue
GROUP BY id
ORDER BY total DESC
The join approach would have worked if you used a FULL OUTER JOIN, because some ids may be present in one table but not the other, but that is usually less performant.
Looks like you just need to group on the ID then... unless I'm missing something.
select d.* from (
SELECT
table1.id,
Sum(table1.rev) + Sum(table2.rev) as revenue
FROM table1
INNER JOIN table2 ON table1.id = table2.id
GROUP BY
table1.id) d
order by d.revenue
SELECT id, SUM(rev) as total
FROM (
SELECT id, rev FROM table1 UNION ALL
SELECT id, rev FROM table2
)
GROUP BY id
ORDER BY total DESC

Selecting row with max date from multiple almost identical tables

If I can retrieve the most recent name for each id from a table in a MySQL database like so:
SELECT n.id, n.name, n.date
FROM $table AS n
INNER JOIN
(SELECT id, MAX(date) AS date
FROM $table GROUP BY id)
AS max
USING (id, date);
How could I retrieve the most recent name from three almost identical tables (call them $table, $table2, $table3)? They all share the same column structure and the id found from one table may or may not be present in the other two. Think of it as one large table split into three (but with two of them containing two extra columns that are irrelevant in this instance). Would UNION be the best solution? If so, is there a way to do it without a mile-long query?
Constraint:
id is not an auto-incrementing unique integer unfortunately
You can use union all. One slight simplification is the group_concat()/substring_index() trick:
select id, max(date) as date,
substring_index(group_concat(name order by date desc), ',', '') as MostRecentName
from (select t.* from $table1 t union all
select t.* from $table2 t union all
select t.* from $table3
) t
group by id;
This does make certain assumptions. The name cannot contain , (although it is easy enough to change the separator. In addition, the intermediate result for the group_concat() cannot exceed a certain threshold (which is determined by a user-settable system parameter).
You could try:
SELECT n.id, n.name, n.date
FROM table1 where id in (select max(id) from table1)
union
SELECT n.id, n.name, n.date
FROM table2 where id in (select max(id) from table2)
union
SELECT n.id, n.name, n.date
FROM table3 where id in (select max(id) from table3)
Every inner query selects the highest id from the table and then searches for the corresponding fields in the outer query.
This ended up being the only solution I could think of:
SELECT n.id, n.name, n.date FROM (
SELECT id, name, date FROM $table
UNION ALL
SELECT id, name, date FROM $table2
UNION ALL
SELECT id, name, date FROM $table3
) AS n INNER JOIN (
SELECT id, MAX(date) AS date FROM (
SELECT id, date FROM $table
UNION ALL
SELECT id, date FROM $table2
UNION ALL
SELECT id, date FROM $table3
) AS t
GROUP BY id
) AS max USING (id, date)

Count(*) Multiple Tables

I was browsing for a solution to getting counts from multiple tables and I came across the following answer:
SELECT COUNT(*),(SELECT COUNT(*) FROM table2) FROM table1
It works great, however I can't seem to get it to work for more than just 2 tables. My current code is as follows:
SELECT COUNT(*),
(SELECT COUNT(*) FROM TABLE1),
(SELECT COUNT(*) FROM TABLE2),
(SELECT COUNT(*) FROM TABLE3),
(SELECT COUNT(*) FROM TABLE4),
(SELECT COUNT(*) FROM TABLE5),
(SELECT COUNT(*) FROM TABLE6),
(SELECT COUNT(*) FROM TABLE7),
(SELECT COUNT(*) FROM TABLE8),
(SELECT COUNT(*) FROM TABLE9),
(SELECT COUNT(*) FROM TABLE10),
(SELECT COUNT(*) FROM TABLE11),
(SELECT COUNT(*) FROM TABLE12),
(SELECT COUNT(*) FROM TABLE13),
(SELECT COUNT(*) FROM TABLE14),
(SELECT COUNT(*) FROM TABLE15),
(SELECT COUNT(*) FROM TABLE16),
(SELECT COUNT(*) FROM TABLE17),
(SELECT COUNT(*) FROM TABLE18)
FROM TABLE19
However, it only counts TABLE1 and TABLE19. I need to count all tables (TABLE1-18) as well as TABLE19 (hopefully using a structure to similar to the first example).
Depending on which DB this is it could slightly change...
For Oracle do something like:
Select (select count(*) from table1) as table1Count,
(select count(*) from table2) as table2Count
from dual
If it's SQL Server then just leave off the from dual.
EDIT:
Since you mentioned you are using MySQL in the comments:
Get record counts for all tables in MySQL database
Use aliases so that the columns have unique names:
SELECT
(SELECT COUNT(*) FROM TABLE1) AS count_table1,
(SELECT COUNT(*) FROM TABLE2) AS count_table2,
(SELECT COUNT(*) FROM TABLE3) AS count_table3,
etc..
(SELECT COUNT(*) FROM TABLE19) AS count_table19
If you are happy to accept the results in rows, not columns, you can always use a UNION:
SELECT "table1", COUNT(*) FROM table1 UNION
SELECT "table2", COUNT(*) FROM table2 UNION
SELECT "table3", COUNT(*) FROM table3
etc.
On MySQL this works:
select sum(total) from(
select count(*) as total from Table1
union
select count(*) as total from Table2) as a;