How to divide two SELECT statements to get a percentage with SQL - 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 ;

Related

SQL Query to sum multiple count union queries

I have a statement with following structure, and I'm trying to sum all the count results.
I have tried using the SUM function outside of the nested count queries combined using the same variable declaration for each of the union, but error says that I must give them separate aliases. However, if I do that, won't I need to refer to these separately within the SUM function?
My SQL Code returning 2 rows:
SELECT COUNT(col_x) FROM tablea
UNION
SELECT COUNT(col_y) FROM tableb;
OUTPUT
64
10
Now when I try to SUM the answers I run into trouble:
WITH total as(
SELECT COUNT(col_x) FROM tablea as rowtotal
UNION
SELECT COUNT(col_y) FROM tableb as rowtotal
) SELECT SUM(rowtotal) from total;
The error is around using the variable 'rowtotal' twice. Surely there's an easier way to this?
I simply want a sum of both values as:
OUTPUT
74
You don't need window functions for that
select sum(cnt) as total
from
(
SELECT COUNT(col_x) as cnt FROM tablea
UNION
SELECT COUNT(col_y) FROM tableb
) tmp
You can use +:
SELECT ( (SELECT COUNT(col_x) FROM tablea) +
(SELECT COUNT(col_y) FROM tableb)
)
Or a cross join:
SELECT a_cnt + b_cnt
FROM (SELECT COUNT(col_x) as a_cnt FROM tablea) a CROSS JOIN
(SELECT COUNT(col_y) as b_cnt FROM tableb) b;
Do not use UNION! It removes duplicates, so your sum may be off. You can use UNION ALL, but you have alternatives.
Try this
WITH total as(
SELECT COUNT(col_x) as rowtotal FROM tablea
UNION
SELECT COUNT(col_y) FROM tableb
) SELECT SUM(rowtotal) from total
You don;t need to give alias on table, instead it is actually saying to provide alias for column name.
WITH total as(
SELECT COUNT(col_x) as total FROM tablea --- it is necessary over here
UNION
SELECT COUNT(col_y) as total FROM tableb --- it is not mandatory to give alias on second statement of UNION
) SELECT SUM(rowtotal) as total from total;

Oracle CASE failing with multiple columns in Else clause

In Oracle below query is working fine with single column but when I tried to put multiple columns it fails, Actually my requirement is to Exit SQL query if there is no records in particular table and its complex inner query (below is simplified problem description) and I cannot use PL/SQL block, please suggest.
SQL> select
case when (select count(*) from bl1_charge_adj where rownum=1) = '1' then ( select customer_id from customer)
else 44 END as ee
from dual;
EE
----------
44
SQL> select
case when (select count(*) from bl1_charge_adj where rownum=1) = '1' then ( select customer_id,DL_UPDATE_STAMP from customer)
else (1,2) END
from dual
ERROR at line 1:
ORA-00907: missing right parenthesis
I think you want something like this:
select customer_id, DL_UPDATE_STAMP
from customer
where exists (select 1 from bl1_charge_adj)
union all
select 1, 2
from dual
where not exists (select 1 from bl1_charge_adj);
This should work:
select nvl(c.customer_id, 1), nvl(c.DL_UPDATE_STAMP, 2)
from ( select count(*) as c from bl1_charge_adj where rownum=1) d
left outer join customer c on d.c = 1;
I suspect it would be better done by changing the count(*) to something else if the bl1_charge_adj table is big.

DB2 SQL column percentage calculation

Need to calculate a percentage of filled rows in a column(string).
String column could contain zero length strings (should be excluded)
How to re-write this SQL in one sentence (without WITH operator)?
with A(COUNT) // needed rows
as(
select count(FAMILY) from T1
where length(FAMILY)>0
),
B(COUNT) // total rows
as(
select count(*) from T1)
select A.COUNT*100/B.COUNT from A,B
You can use sub-selects instead of WITH; for example:
select
((select count(*) from T1 where length(FAMILY) > 0) * 100) /
(select count(*) from T1)
from sysibm.sysdummy1

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).

Count rows in more than one table with tSQL

I need to count rows in more than one table in SQL Server 2008. I do this:
select count(*) from (select * from tbl1 union all select * from tbl2)
But it gives me an error of incorrect syntax near ). Why?
PS. The actual number of tables can be more than 2.
In case you have different number of columns in your tables try this way
SELECT count(*)
FROM (
SELECT NULL as columnName
FROM tbl1
UNION ALL
SELECT NULL
FROM tbl2
) T
try this:
You have to give a name to your derived table
select count(*) from
(select * from tbl1 union all select * from tbl2)a
I think you have to alias the SELECT in the FROM clause:
select count(*)
from
(
select * from tbl1
union all
select * from tbl2
) AS SUB
You also need to ensure that the * in both tables tbl1 and tbl2 return exactly the same number of columns and they have to be matched in their type.
I don't like doing the union before doing the count. It gives the SQL optimizer an opportunithy to choose to do more work.
AlexK's (deleted) solution is fine. You could also do:
select (select count(*) from tbl1) + (select count(*) from tbl2) as cnt