How to take sum of two different query result counts in mysql? - mysql

I need to take total count of files from category + sub category + subsub category
For that I write this kind of a query using my views.
select ((select count(*) from view_category where 1=1)+ (select count(*) from view sub category where 1=1) + (select count(*) from view subsub category where 1=1)) as cnt
Its returning count value. But I want to know any other better method is available to get the same result.
I tried this way but its not working (How to SUM() multiple subquery rows in MySQL?)
select sum(int_val) from((select count(*) from view_category where 1=1) as int_val union (select count(*) from view sub category where 1=1) as int_val union (select count(*) from view subsub category where 1=1) as int_val ).

you don't need to do a union, and can just have each as its own from alias... As long as each query is returning only one row, you can do all sorts of crazy things. By ignoring any "join" condition, you get a Cartesian result, but a Cartesian of 1:1:1 will result with only 1 record
select
ByCat.CatCount
+ BySubCat.SubCatCount
+ BySubSubCat.SubSubCatCount as Cnt
from
( select count(*) CatCount
from view_category ) ByCat,
( select count(*) SubCatCount
from view_sub_category) BySubCat,
(select count(*) SubSubCatCount
from view_subsub_category ) BySubSubCat
Also imagine if you needed sum() or AVG() counts too from other elements... You could get those into a single row and use however you needed.

If the tables have similar structure, you might use UNION to unite the result and then perform one COUNT(*).

This is working for me
select count(*) from(
(select count(*) from view_category where 1=1) union (select count(*) from view sub category where 1=1) union (select count(*) from view subsub category where 1=1) ) AS int_val;

Related

how to use min as a condition in sql query

cat use min as condition
the where statement is where it breaks but i cant fix it
select category, count(*) as number_of_cats
from books
where number_of_cats > min(number_of_cats)
group by category
order by category;
Having + sub-query
select category, count(*) as number_of_books
from books
group by category
having count(*) > -- check the one whose count is STRICTLY greater then minimum
( select min (st.t) -- find the minimum of all categories
from
( select count(*) as t --find the count for all categories
from books
group by category
) st -- an alias to avoid parsing errors
)
Another option, but with this solution in case of ex-aequo only first category is removed:
select select category, count(*) as number_of_books
from books
where category not in (select bb.category
from books bb
group by bb.category
order by count(*) asc
limit 1)
group by category
You could use common table expressions here, e.g.:
WITH CategoryCount AS (
SELECT
category,
COUNT(*) AS number_of_books
FROM
books
GROUP BY
category),
MinBooks AS (
SELECT
MIN(number_of_books) AS min_number_of_books
FROM
CategoryCount)
SELECT
cc.*
FROM
CategoryCount cc
CROSS JOIN MinBooks m
WHERE
cc.number_of_books > m.min_number_of_books;

Select distincts of same column in mutiple tables sql

SQL novice here.
I have this schema:
What I need in plain English is:
"Out of the 2 columns, make one above the other in one column, and then count how many distincts values there is"
I've tried
SELECT COUNT (DISTINCT uid ) from nodes UNION SELECT COUNT (DISTINCT uid) from ways ;
SELECT distinct nodes.uid from nodes JOIN ways on nodes.uid = ways.uid ;
sqlite> SELECT COUNT (DISTINCT uid ) from nodes UNION SELECT COUNT (DISTINCT uid) from ways ;
1195
2182
sqlite> SELECT uid from nodes FULL OUTER JOIN ways on nodes.uid = ways.iud ;
Error: RIGHT and FULL OUTER JOINs are not currently supported
SELECT COUNT (DISTINCT iud) FROM (SELECT DISTINCT uid from nodes as uid UNION SELECT DISTINCT uid from ways as uid as subq);
SELECT count (distinct nodes.uid) from nodes JOIN ways on nodes.uid = ways.uid ;
takes ages and i'm not sure nodes.uid = ways.uid is the correct way to go
Any idea ?
I think i got it
SELECT COUNT (DISTINCT uid) from (SELECT DISTINCT uid from nodes UNION SELECT DISTINCT uid from ways) as subq ;
Since UNION returns a distinct set of the joining tables you dont need to use the DISTINCT keyword
SELECT COUNT(uid) Cnt
FROM (
SELECT uid
FROM nodes
UNION
SELECT uid
FROM ways
) t

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`;

How to do a count on a union query

I have the following query:
select distinct profile_id from userprofile_...
union
select distinct profile_id from productions_...
How would I get the count of the total number of results?
If you want a total count for all records, then you would do this:
SELECT COUNT(*)
FROM
(
select distinct profile_id
from userprofile_...
union all
select distinct profile_id
from productions_...
) x
you should use Union All if there are equals rows in both tables, because Union makes a distinct
select count(*) from
(select distinct profile_id from userprofile_...
union ALL
select distinct profile_id from productions_...) x
In this case, if you got a same Profile_Id in both tables (id is probably a number, so it's possible), then if you use Union, if you got Id = 1 in both tables, you will lose one row (it will appear one time instead of two)
This will perform pretty well:
select count(*) from (
select profile_id
from userprofile_...
union
select profile_id
from productions_...
) x
The use of union guarantees distinct values - union removes duplicates, union all preserves them. This means you don't need the distinct keyword (the other answers don't exploit this fact and end up doing more work).
Edited:
If you want to total number of different profile_id in each, where given values that appear in both table are considered different values, use this:
select sum(count) from (
select count(distinct profile_id) as count
from userprofile_...
union all
select count(distinct profile_id)
from productions_...
) x
This query will out-perform all other answers, because the database can efficiently count distinct values within a table much faster than from the unioned list. The sum() simply adds the two counts together.
These will not work if in one of the COUNT(*) the result is equals to 0.
This will be better:
SELECT SUM(total)
FROM
(
select COUNT(distinct profile_id) AS total
from userprofile_...
union all
select COUNT(distinct profile_id) AS total
from productions_...
) x
As omg ponies has already pointed out that there is no use of using distinct with UNION, you can use UNION ALL in your case.....
SELECT COUNT(*)
FROM
(
select distinct profile_id from userprofile_...
union all
select distinct profile_id from productions_...
) AS t1
Best solution is to add count of two query results. It will not be a problem if the table contains large number of records. And you don't need to use union query.
Ex:
SELECT (select COUNT(distinct profile_id) from userprofile_...) +
(select COUNT(distinct profile_id) from productions_...) AS total