simple sql query, combine results and divide - sql

I'm trying to get 2 counts from 2 tables and work out the percentage like for a MySQL db:
select field_one, count(*) as COUNT_ONE from table1 group by field_one;
select other_field,count(*) as COUNT_TWO from table2 group by other_field;
I want to combine the results and have FINAL_COUNT=(COUNT_ONE/COUNT_TWO) * 100 for percentage ?

quick and dirty:
select (a.count_one / b.count_two) * 100 as final_count from
(select field_one, count(*) as count_one from table1 group by field_one) a,
(select field_two, count(*) as count_two from table2 group by field_two) b
where a.field_one = b.field_two

select sum(((QUERY FROM TABLE 1) / (QUERY FROM TABLE 2)) * 100) as percentage

Related

How to divide two SELECT statements to get a percentage with SQL

I'm trying to calculate the the percentage of items sent by royal mail from the delivery table.
(SELECT post_method
FROM delivery_tbl
WHERE post_method = 'RM')
/
SELECT post_method
FROM delivery_tbl;
I get an error saying
"SQL command not properly ended".
Any help on this would be great! Thanks!
You can do this using conditional aggregation, like so:
SELECT round (100 * (count(case when post_method = 'RM' then 1 end) / count(*)), 2) royal_mail_items_percentage
FROM delivery_tbl;
I've included the round function as it looks like you only want to display up to 2 decimal places.
Doing the query using conditional aggregation means you only have to query the table once, so it should be more performant than the other answers, which need to hit the table more than once.
Select post_method, (Count(post_method)* 100 / (Select Count(*) From
delivery_tbl)) as percentage
From delivery_tbl
Where post_method = 'RM'
Group By post_method
You are doing a division of 2 queries, but to properly display the result, you need to add a SELECT statement of the division.
This is wrong:
-- Result: SQL command not properly ended
(SELECT 100 FROM DUAL) / (SELECT 50 FROM DUAL)
This is OK:
-- Result: 2
SELECT
(SELECT 100 FROM DUAL) / (SELECT 50 FROM DUAL)
FROM
DUAL
You should also try to add column names so it's clearer:
-- ResultOfDivision: 2
SELECT
(SELECT 100 FROM DUAL) / (SELECT 50 FROM DUAL) ResultOfDivision
FROM
DUAL
Please keep in mind that when doing these type of divisions (or any arithmetic operation) between subqueries, each subquery must return 1 row. If they don't then the SQL engine wouldn't know which row to use and throws an error.
-- Result: single-row subquery returns more than one row.
SELECT
(SELECT 100 FROM DUAL) / (SELECT SomeColumn FROM YourTableWithManyRows) ResultOfDivision
FROM
DUAL
For this last example, the correct expression would be the following (for each row).
SELECT
(100 / SomeColumn) ResultOfDivision
FROM
YourTable
WHERE
SomeColumn <> 0 -- Prevent division by 0!!
For your case, seems that you are trying to see the following:
-- Make sure SELECT COUNT(1) FROM delivery_tbl isnt 0!
SELECT
post_method,
COUNT(post_method) * 100 / (SELECT COUNT(1) FROM delivery_tbl) 100perc, -- 100 based percentage
COUNT(post_method) / (SELECT COUNT(1) FROM delivery_tbl) 1perc -- 1 based percentage
FROM
delivery_tbl
GROUP BY
post_method
SELECT ((SELECT post_method FROM delivery_tbl Where post_method = 'RM')/ (SELECT post_method FROM delivery_tbl))*100 as royalperc
Updated query to get counts instead
SELECT ((SELECT COUNT(post_method) FROM delivery_tbl Where post_method = 'RM')/ (SELECT COUNT(post_method) FROM delivery_tbl))*100 as royalperc
I believe you should use the second query
Add a SELECT statement at the beginning:
SELECT ((SELECT post_method FROM delivery_tbl Where post_method = 'RM') / (SELECT post_method FROM delivery_tbl));
Use the sql:
select (
(select sum(post_method) from delivery_tbl where post_method = 'RM') /
(select sum(post_method) from delivery_tbl)) * 100 as "royalperc" from dual ;

Trying to divide two counts in SQL

so I'm trying to do simple division and of course SQL, being super logical that it is, makes it impossible. What I am trying to do is this:
SELECT * FROM
1 - ((SELECT COUNT(DISTINCT T.DID) FROM TGAMAZING T AS NUM) * 100 /
(SELECT COUNT(DISTINCT D.ID) FROM DIRECTORS D AS DENOM))
but how would I write this SQL (Oracle)?
Oracle
SQL Fiddle: http://sqlfiddle.com/#!4/34298/8
Method 1:
SELECT 1 - (COUNT(DISTINCT DID) * 100 / COUNT(DISTINCT ID))
FROM TGAMAZING
cross join DIRECTORS;
Method 2:
SELECT 1 -
(
(SELECT COUNT(DISTINCT DID) FROM TGAMAZING) * 100 /
(SELECT COUNT(DISTINCT ID) FROM DIRECTORS)
)
FROM DUAL;
SQL Server
SQL Fiddle: http://sqlfiddle.com/#!6/34298/3
Method 1
SELECT 1 - (COUNT(DISTINCT DID) * 100.0 / COUNT(DISTINCT ID))
FROM TGAMAZING
cross join DIRECTORS;
Method 2
SELECT 1 -
(
(SELECT COUNT(DISTINCT DID) FROM TGAMAZING) * 100.0 /
(SELECT COUNT(DISTINCT ID) FROM DIRECTORS)
)
Write the calculation as it were fields and use "FROM DUAL", as you don't want to query any of your tables.
SELECT
1 - ((SELECT COUNT(DISTINCT T.DID) FROM TGAMAZING T) * 100 /
(SELECT COUNT(DISTINCT D.ID) FROM DIRECTORS D))
AS RESULT
FROM DUAL
Reference: Selecting from the DUAL Table.

How can I get the count of multiple columns in SQL

Say I had two tables in SQL. Now I would like to get the quotient of the count of table 1 and count of table 2. How can I do that?
In Short:
(# of rows in table 1) / (# of rows in table 2)
EDIT:
This is what I tried:
SELECT COUNT(t1.a) / COUNT(t2.a)
FROM table1 t1, table2 t2
Here's one way to get the result:
SELECT c1.cnt / c2.cnt AS q
FROM ( SELECT COUNT(1) AS cnt
FROM table1
) c1
CROSS
JOIN ( SELECT COUNT(1) AS cnt
FROM table2
) c2
Another way to get an equivalent result:
SELECT (SELECT COUNT(1) FROM table1) / (SELECT COUNT(1) FROM table2) AS q
I would prefer the first query if I also needed to return the counts from the tables as separate columns in the resultset, for example:
SELECT c1.cnt AS table1_count
, c2.cnt AS table2_count
, c1.cnt / c2.cnt AS q
FROM ...
Try this:
SELECT COUNT(table1.column) as 'Table 1 Count'
,COUNT(table2.column) as 'Table 2 Count'
,COUNT(table1.column) / COUNT(table2.column) as 'Quotient'
FROM table1, table2
with
Ctable1 as
(select count(*) as num1 from table1),
Ctable2 as
(select count(*) as num2 from table2)
select num1 / num2 as quotient
from Ctable1,Ctable2
Remember:
When you count column, rows with "NULL" data will NOT count. (If you use Oracle, you can use count(a.*)
Int division in sql like most languages, returns int. (5/2 = 2 and not 2.5).

How to get Original Rows filtered by a HAVING Condition?

What is the method in T-SQL to select the orginal values limited by a HAVING attribute. For example, if I have
A|B
10|1
11|2
10|3
How would I get all the values of B (Not An Average or some other summary stat), Grouped by A, having a Count (Occurrences of A) greater than or equal two 2?
Actually, you have several options to choose from
1. You could make a subquery out of your original having statement and join it back to your table
SELECT *
FROM YourTable yt
INNER JOIN (
SELECT A
FROM YourTable
GROUP BY
A
HAVING COUNT(*) >= 2
) cnt ON cnt.A = yt.A
2. another equivalent solution would be to use a WITH clause
;WITH cnt AS (
SELECT A
FROM YourTable
GROUP BY
A
HAVING COUNT(*) >= 2
)
SELECT *
FROM YourTable yt
INNER JOIN cnt ON cnt.A = yt.A
3. or you could use an IN statement
SELECT *
FROM YourTable yt
WHERE A IN (SELECT A FROM YourTable GROUP BY A HAVING COUNT(*) >= 2)
A self join will work:
select B
from table
join(
select A
from table
group by 1
having count(1)>1
)s
using(A);
You can use window function (no joins, only one table scan):
select * from (
select *, cnt=count(*) over(partiton by A) from table
) as a
where cnt >= 2

How to get rows from a table if total rows are more than 10 in Oracle?

I want to write a Oracle based query where I can choose if I want to see the results. Let's say:
SELECT *
FROM table
//when there are more than 10 rows
How can I do this?
select * from table
where 10 < (select count(*) from table)
Best speed:
select * from table
where 10=(select count(*) from
table
where rownum <11)
:)
UPDATE: Because there are suspicions that I claim something that is not true, here some tests:
In SQL Developer(keep in mind that select * from table will offer only first 50 rows, but count(*) read all requested rows)
The table has no indexes.
select
count(*) from
table
22074412 rows
3.16 seconds
select * from table where 10 =
(select
count(*) from
table
where rownum <11
)
0.051 seconds
select * from table where 10 <
(select
count(*) from
table
)
3.39 seconds
select count(*) from table where 10 <
(select
count(*) from
table
)
7.69 seconds
select count(*) from table where 10 =
(select
count(*) from
table
where rownum <11
)
3.42 seconds
Cause: Subquery with rownum is faster (it reads not the entire table)
DECLARE #Var int;
SET #Var = SELECT COUNT(*) FROM [somewhere]
IF #Var > 10
BEGIN
SELECT * FROM [somewhere]
END
You mean something like that?
Or just how to use the where clause?
SELECT *
FROM [somewhere]
WHERE (SELECT COUNT(*) FROM [somewhere]) > 10
This should do it for you:
SELECT * FROM [table] WHERE (SELECT COUNT(1) FROM [table]) > 10
select * from YourTable where (select count(*) from YourTable ) > 10
if you would like to avoid double scans and you have valid statistics you can
select * from table a, all_tables b
where b.num_rows > 10
and b.table_name = 'table';