Combining 3 Tables and Finding Average Age in SQL - sql

I need to combine three tables and find the average age after combining the three tables using SQL. The name of the age columns in the three tables are pr16pnk.age, pr16puf.age, and pr16yag.age. I have successfully found the results when the tables are separated, but I am having trouble combining the results. Listed below is the code that I used.
SELECT AVG(pr16pnk.age) AS MeanAge
FROM pr16pnk
UNION ALL
SELECT AVG(pr16puf.age) AS MeanAge
FROM pr16puf
UNION ALL
SELECT AVG(pr16yag.age) AS MeanAge
FROM pr16yag

You can use two levels of aggregation. For the average of averages:
SELECT AVG(MeanAge)
FROM (SELECT AVG(pr16pnk.age) AS MeanAge
FROM pr16pnk
UNION ALL
SELECT AVG(pr16puf.age) AS MeanAge
FROM pr16puf
UNION ALL
SELECT AVG(pr16yag.age) AS MeanAge
FROM pr16yag
) a;
However, what you might really want is the overall average, which would be calculated as:
SELECT AVG(MeanAge),
SUM(sum_age) / SUM(cnt)
FROM (SELECT AVG(pr16pnk.age) AS MeanAge, SUM(age) as sum_age, COUNT(*) as cnt
FROM pr16pnk
UNION ALL
SELECT AVG(pr16puf.age) AS MeanAge, SUM(age) as sum_age, COUNT(*) as cnt
FROM pr16puf
UNION ALL
SELECT AVG(pr16yag.age) AS MeanAge, SUM(age) as sum_age, COUNT(*) as cnt
FROM pr16yag
) a;

Related

How can I get the percentage of the sum of the top 5 countries in SQL?

I want to calculate the percentage of the sum of the top 5 countries by number of customers compared to the total number of customers. The SQL Editor rounds decimals, therefore the counter of my calculation needs to be multiplied by 100 before dividing it.
I have tried the following SQL statement:
SELECT
A.NUM, A.DENOM, cast(A.NUM as float)/cast(A.DENOM as float)
FROM
(
SELECT
(SELECT SUM(count_five) * 100
FROM(
SELECT *, COUNT(*) AS count_five
FROM Customers
GROUP BY Country
ORDER BY count_five DESC
LIMIT 5)
AS NUM,
(SELECT SUM(count_all) * 100
FROM(
SELECT *, COUNT(*) AS count_all
FROM Customers
GROUP BY Country)
AS DENOM
)A
Here is the table:
https://www.w3schools.com/sql/trysql.asp?filename=trysql_asc
Hmmm . . . This would use window functions and conditional aggregation:
SELECT SUM(CASE WHEN seqnum <= 5 THEN cnt END) / SUM(cnt) as top_5_ratio
FROM (SELECT Country, COUNT(*) AS cnt,
ROW_NUMBER() OVER (ORDER BY COUNT(*) DESC) as seqnum
FROM Customers
GROUP BY Country
) c;
Note that your code has SELECT * with GROUP BY. That is pretty close to blasphemy in SQL -- it is a construct that generates an error in almost all databases. The unaggregated SELECT expressions need to be consistent with the GROUP BY expressions in an aggregation query.

The SUM of an aggregate COUNT function

I want to create a query to calculate the percentage sales of the overall policies in my database.
The policies are split under two separate headings
UL
NL
The code i want should display
product name
number of policies sold
policies sold per product as a percentage of the overall number of policies sold.
I have made a few attempts at scripting this code (please see below) but cannot get them to run correctly.
Syntax 1:
SELECT b.PRODUCT_NAME, b.POLICIES_SOLD, 100.00*(b.POLICIES_SOLD/SUM(b.POLICIES_SOLD)) AS'PERC_SALES'
FROM
(
SELECT a.PRODUCT_NAME, COUNT(a.PRODUCT_NAME) AS
'POLICIES_SOLD'
FROM
(SELECT PRODUCT_NAME FROM [ATLANTIS\jjudge].
[ALL_POLICIES_201706_NL]
UNION ALL
SELECT PRODUCT_NAME FROM [ATLANTIS\jjudge].
[ALL_POLICIES_201706_UL])a GROUP BY PRODUCT_NAME)b ;
Syntax 2:
SELECT a.PRODUCT_NAME, a.[POLICIES SOLD], 100.00*(a.[POLICIES SOLD]/SUM(a.[POLICIES SOLD]))
FROM
(SELECT PRODUCT_NAME, COUNT(*) AS 'POLICIES SOLD'FROM
[ATLANTIS\jjudge].[ALL_POLICIES_201706_NL] GROUP BY PRODUCT_NAME
UNION ALL
SELECT PRODUCT_NAME, COUNT(*) AS 'POLICIES SOLD' FROM
[ATLANTIS\jjudge].[ALL_POLICIES_201706_UL] GROUP BY
PRODUCT_NAME)a ;
Syntax 3:
SELECT b.PRODUCT_NAME, COUNT(b.PRODUCT_NAME) AS
'POLICIES_SOLD', 100.00*
(COUNT(b.PRODUCT_NAME)/SUM(SELECT(PRODUCT_NAME))
FROM
(SELECT COUNT(*) AS 'POLICY_COUNT' FROM [ATLANTIS\jjudge].[ALL_POLICIES_201706_NL]
UNION ALL
SELECT COUNT(*) AS 'POLICY_COUNT' FROM [ATLANTIS\jjudge].[ALL_POLICIES_201706_UL])a)) AS 'PERC_SALES'
FROM
(SELECT PRODUCT_NAME FROM [ATLANTIS\jjudge].
[ALL_POLICIES_201706_NL]
UNION ALL
SELECT PRODUCT_NAME FROM [ATLANTIS\jjudge].
[ALL_POLICIES_201706_UL])b GROUP BY PRODUCT_NAME;
I think you want a Window Function. Modify your Syntax 1 first line as:
SELECT
b.PRODUCT_NAME,
b.POLICIES_SOLD,
100.00*b.POLICIES_SOLD/SUM(b.POLICIES_SOLD) OVER () AS 'PERC_SALES'
You can do this using a single aggregation query with window functions:
SELECT p.PRODUCT_NAME, COUNT(*) AS POLICIES_SOLD,
COUNT(*) * 100.0 / SUM(COUNT(*)) OVER () as PERC_SALES
FROM ((SELECT PRODUCT_NAME
FROM [ATLANTIS\jjudge].[ALL_POLICIES_201706_NL]
) UNION ALL
(SELECT PRODUCT_NAME
FROM [ATLANTIS\jjudge].[ALL_POLICIES_201706_UL]
)
) p
GROUP BY PRODUCT_NAME;

How to get a combined count on two tables for shared id

I have two transcript tables, A_Transcript and B_Transcript, and I want a query that will give me all the users who have more than 2 total transcripts (across both tables). Thanks!
Here's the query if I just had one table with data:
select user_Id, count(*) From A_Transcript
group by user_ID
having count(*) > 2;
You need to get the full list of userids from both tables before grouping, and you need UNION ALL to do a non-distinct union:
SELECT user_Id, count(*)
FROM
(
SELECT user_Id
FROM A_Transcript a
UNION ALL
select user_Id
FROM B_Transcript b
) combined
GROUP BY user_Id
HAVING COUNT(*) >2
You can just union the 2 queries together.
SELECT user_Id, count(*) FROM A_Transcript
GROUP BY user_ID
HAVING count(*) > 2
UNION
SELECT user_Id, count(*) FROM B_Transcript
GROUP BY user_ID
HAVING count(*) > 2

combine 2 sql select count statements

I ahave 2 simple count queries:
select count (*) from t_object
select count (*) from t_diagram
How is the simplest way to combine their result (sum)?
Use UNION ALL to get two different count:
select count (*), 't_object count' from t_object
union all
select count (*), 't_diagram count' from t_diagram
To get the sum of the counts, use a derived table:
select sum(dt.cnt) from
(
select count(*) as cnt from t_object
union all
select count(*) as cnt from t_diagram
) dt
Or, use a sub-query:
select count(*) + (select count(*) from t_diagram) from t_object
Depends on what you mean by "combine". To sum them up:
select (select count (*) from t_object) + count(*) as combined_count
from t_diagram

SQL for counting rows and categorize

Is it possible to do the following for count >=3,4,5,6,7,8 etc.
rather than repeating the entire code for each count category
Insert into OnePlus (SELECT DISTINCT Id, Name, COUNT(DISTINCT StartDate) AS OnePlusDays
FROM DataTable
HAVING OnePlusDays >= 1
GROUP BY Id, Name)
Insert into TwoPlus (SELECT DISTINCT Id, Name, COUNT(DISTINCT StartDate) AS TwoPlusDays
FROM DataTable
HAVING TwoPlusDays >= 2
GROUP BY Id, Name)
Finally
SELECT Id, Name, "1+" AS Categories
FROM OnePlus
UNION
SELECT Id, Name, "2+" AS Categories
FROM TwoPlus
You mention only sql in the tags. Depending on MySql or SQL Server, you may need to change the Cast/Convert and Concatenation. But this query may help. You really don't need to put a Distinct on top a group by, the fact that you are grouping by, means only distinct values and their counts will be fetched.
Of course, the table OnePlus, is really what you call Categories.
Insert into OnePlus
SELECT Id, Name, convert(varchar(10), COUNT(DISTINCT StartDate) ) + "+" AS Categories
FROM DataTable
GROUP BY Id, Name
In T-SQL you can write as:
SELECT Id,
NAME , -- make sure you write case statement in desc order
CASE WHEN PlusDays > = 2 THEN '2+'
WHEN PlusDays > = 1 THEN '1+' END AS Categories
FROM
(
SELECT DISTINCT Id, Name, COUNT(DISTINCT StartDate) PlusDays
FROM #DataTable
GROUP BY Id, Name
) AS T
ORDER BY Id asc