How to show the difference between two counts using aliases? - mysql

I'm creating custom views that show totals for different things in a database, and I'd like to also show the differences.
For example;
SELECT
(SELECT COUNT(*) FROM `documents`) AS `doc_count`,
(SELECT COUNT(*) FROM `contacts`) AS `user_count`,
(`doc_count` - `user_count`) AS `difference`;
I get an error using the aliases this way. Is there a way to write this query without repeating select count(*) queries?

You could wrap both queries with an additional query:
SELECT doc_count, user_count, doc_count - user_count AS difference
FROM ((SELECT COUNT(*) FROM `documents`) AS doc_count,
(SELECT COUNT(*) FROM `contacts`) AS user_count) t

No you can't use the aliases at same level of query you have to use the whole expression or use sub select
SELECT
(SELECT COUNT(*) FROM `documents`) AS `doc_count`,
(SELECT COUNT(*) FROM `contacts`) AS `user_count`,
((SELECT COUNT(*) FROM `documents`) - (SELECT COUNT(*) FROM `contacts`)) AS `difference`;

Here is a "workaround" to get the result you're looking for:
SELECT C.doc_count
,C.user_count
,C.doc_count - C.user_count AS `difference`
FROM (SELECT
(SELECT COUNT(*) FROM `documents`) AS `doc_count`
,(SELECT COUNT(*) FROM `contacts`) AS `user_count`) C
But i'm not sure about the performance of such kind of query...
Hope this will help you

I would move these to the from clause and use cross join:
SELECT d.doc_count, u.user_count, (d.doc_count - u.user_count) as difference
FROM (SELECT COUNT(*) as doc_count FROM `documents`) d CROSS JOIN
(SELECT COUNT(*) as user_count FROM `contacts`) u;

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

SQL - Select multiply conditions

I would like to select multiply conditions using below query:
SELECT (SELECT count(*)
FROM users
)
as totalusers,
(SELECT sum(cashedout)
FROM users
) AS cashedout,
(SELECT COUNT(*)
FROM xeon_users_rented
) AS totalbots,
(SELECT sum(value)
FROM xeon_stats_clicks
WHERE typ='3' OR typ='1'
) AS totalclicks
The above query takes just under a second (0.912 to be exact) to execute. This slows things down a lot with thousands of requests.
What seems logical for me is this approach:
SELECT (SELECT count(*), sum(cashedout)
FROM users
)
as totalusers, cashedout,
(SELECT COUNT(*)
FROM xeon_users_rented
) AS totalbots,
(SELECT sum(value)
FROM xeon_stats_clicks
WHERE typ='3' OR typ='1'
) AS totalclicks
However that doesn't work, as I get the following error:
#1241 - Operand should contain 1 column(s)
Furthermore, how can I join the two other tables "xeon_users_rented" and "xeon_stats_clicks" in my first query?
It's slow because you have multiple subqueries. Try using joins instead.
Also, a list of your tables, columns would help us better assist you.
Your 2nd query is using wrong syntax, it should be
SELECT
count(*) as totalusers,
sum(cashedout) cashedout,
(SELECT COUNT(*) FROM xeon_users_rented) AS totalbots,
(SELECT sum(value) FROM xeon_stats_clicks
WHERE typ='3' OR typ='1') AS totalclicks
FROM users

How to get AS two separate selectors with UNION?

As sadly SQL is my weakest skill.
I'm trying to use UNION in a VIEW, where I can get statistics from two different tables with one query.
SELECT COUNT(*) AS `customer_count` FROM `Customers`
UNION
SELECT COUNT(*) AS `supplier_count` FROM `Suppliers`;
[Demo table]
However, it only returns customer_count, with two rows. Is there anyway, to make this work, so it returns customer_count and supplier_count separately?
You would need a cross join to see the results adjacent to each other in one row. So you would select from both the tables without a join condition.
select * from
(select count(*) as customer_count from Customers) x,
(select count(*) as supplier_count from Suppliers) y
select
(SELECT COUNT(*) FROM Customers) as customer_count,
(SELECT COUNT(*) FROM Suppliers) AS supplier_count
Using your Table Demo.
The key is use alias so the field names match on each union select.
In this case TableSource and Total
SELECT 'Customer' as TableSource, Count(City) as Total FROM Customers
UNION
SELECT 'Suppliers' as TableSource, Count(City) as Total FROM Suppliers;
CREATE VIEW `vw_count` AS
select (select count(0) from `tbl`) AS `customer_count`,
(select count(0) from `tbl2`) AS `supplier_count`;

MySQL CROSS JOIN FROM syntax

I have the following query working
SELECT newTable.Score, COUNT(1) AS Total, COUNT(1) / t.count * 100 AS `Frequency`
FROM mytable newTable
CROSS JOIN (SELECT COUNT(1) AS count FROM mytable) t
GROUP BY newTable.Score
ORDER BY Frequency DESC
However, two things I don't understand from the MySQL docs:
1) I don't understand why there isn't a comma, or a join type, specified in the from clause.
Reading the MySQL docs, this seems necessary.
2) What does the 't' represent in the CROSS JOIN clause?
Any advice appreciated.
The t is the same as the newTable - it is an alias name for the table and the temporary table that the subquery builds.
It is easier to read when the optional as keyword is used
SELECT newTable.Score, COUNT(1) AS Total, COUNT(1) / t.count * 100 AS `Frequency`
FROM mytable as newTable
CROSS JOIN (SELECT COUNT(1) AS count FROM mytable) as t
GROUP BY newTable.Score
ORDER BY Frequency DESC
An alias name replaces the original name of the table with a new one to be used in your query. And you need to give subqueries a name to refer to them in your query too.

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;