MULTIPLE COUNTS IN THE SAME QUERY - sql

I have this table, i want to count the number of orders which are of the same type , and the count of all orders, as follow
ord_id type
1 A
2 B
3 A
4 C
Here is the result :
TYPE COUNT TOTAL
A 2 4
B 1 4
C 1 4
where count column is the count of orders based on their type, and total is the total orders.
Here is my code:
SELECT type, COUNT(*)
FROM
table
where type = 'A'
Union
SELECT type, COUNT(*)
FROM
table
where type = 'b';

Use aggregation and window functions:
select
type,
count(*) cnt,
sum(count(*)) over() total
from mytable
group by type

Related

How do i select all columns, plus the result of the sum

I have this select:
"Select * from table" that return:
Id
Value
1
1
1
1
2
10
2
10
My goal is create a sum from each Value group by id like this:
Id
Value
Sum
1
1
2
1
1
2
2
10
20
2
10
20
I Have tried ways like:
SELECT Id,Value, (SELECT SUM(Value) FROM Table V2 WHERE V2.Id= V.Id GROUP BY IDRNC ) FROM Table v;
But the is not grouping by id.
Id
Value
Sum
1
1
1
1
1
1
2
10
10
2
10
10
Aggregation aggregates rows, reducing the number of records in the output. In this case you want to apply the result of a computation to each of your records, task carried out by the corresponding window function.
SELECT table.*, SUM(Value) OVER(PARTITION BY Id) AS sum_
FROM table
Check the demo here.
Your attempt looks correct.
Can you try the below query :
It works for me :
SELECT Id, Value,
(SELECT SUM(Value) FROM Table V2 WHERE V2.Id= V.Id GROUP BY ID) as sum
FROM Table v;
You can do it using inner join to join with selection grouped by id :
select t.*, sum
from _table t
inner join (
select id, sum(Value) as sum
from _table
group by id
) as s on s.id = t.id
You can check it here
Your select is ok if you adjust it just a little:
SELECT Id,Value, (SELECT SUM(Value) FROM Table V2 WHERE V2.Id= V.Id GROUP BY IDRNC ) FROM Table v;
GROUP BY IDRNC is a mistake and should be GROUP BY ID
you should give an alias to a sum column ...
subquery selecting the sum does not have to have self table alias to be compared with outer query that has one (this is not a mistake - works either way)
Test:
WITH
a_table (ID, VALUE) AS
(
Select 1, 1 From Dual Union All
Select 1, 1 From Dual Union All
Select 2, 10 From Dual Union All
Select 2, 10 From Dual
)
SELECT ID, VALUE, (SELECT SUM(VALUE) FROM a_table WHERE ID = v.ID GROUP BY ID) "ID_SUM" FROM a_table v;
ID VALUE ID_SUM
---------- ---------- ----------
1 1 2
1 1 2
2 10 20
2 10 20

Return count of ids where occurrence is equal to 1 in SQL

I have a dataset with a column of ids (e.g.)
ID
1
2
3
3
3
4
4
5
I want to return the count of the rows where an id only appears once. For example, from the above table the query would return count = 3 as only ID 1, 2 and 5 appear once.
This query:
SELECT id
FROM tablename
GROUP BY id
HAVING COUNT(*) = 1
returns all the ids that you want to count, so count them like this:
SELECT COUNT(*)
FROM (
SELECT id
FROM tablename
GROUP BY id
HAVING COUNT(*) = 1
) t
See the demo.
One method is two levels of aggregation
select count(*)
from (select id, count(*) as cnt
from t
group by id
) i
where cnt = 1;

Divide each value of a column by the total count of records in a table

A query that is capable of dividing each value of a column by the total number of records in the table
I tried the following query
select ( (p.rank/count(*)) * 100 ) as rankratio from RankTable p;
I see an error and not able to execute the query.
for example
total records is 5 so (1/5)*100 = 20
RankTable
rank rankratio
1 20
2 40
3 60
4 80
5 100
use analytic count(*) over():
select ( (s.rank/s.total_count) * 100 ) as rankratio
from
(
select rank, count(*) over() as total_count
from RankTable p
)s
order by s.rank;

Return last amount for each element with same ref_id

I have 2 tables, one is credit and other one is creditdetails.
Creditdetails creates new row every day for each of credit.
ID Amount ref_id date
1 2 1 16.03
2 3 1 17.03
3 4 1 18.03
4 1 2 16.03
5 2 2 17.03
6 0 2 18.03
I want to sum up amount of every row with the unique id and last date. So the output should be 4 + 0.
You can use ROW_NUMBER to filter on the latest amount per ref_id.
Then SUM it.
SELECT SUM(q.Amount) AS TotalLatestAmount
FROM
(
SELECT
cd.ref_id,
cd.Amount,
ROW_NUMBER() OVER (PARTITION BY cd.ref_id ORDER BY cd.date DESC) AS rn
FROM Creditdetails cd
) q
WHERE q.rn = 1;
A test on db<>fiddle here
With this query:
select ref_id, max(date) maxdate
from creditdetails
group by ref_id
you get all the last dates for each ref_id, so you can join it to the table creditdetails and sum over amount:
select sum(amount) total
from creditdetails c inner join (
select ref_id, max(date) maxdate
from creditdetails
group by ref_id
) g
on g.ref_id = c.ref_id and g.maxdate = c.date
I think you want something like this,
select sum(amount)
from table
where date = ( select max(date) from table);
with the understanding that your date column doesn't appear to be in a standard format so I can't tell if it needs to be formatted in the query to work properly.

how to query the percentage of aggregate in vertica

Table product
productId type
1 A
2 A
3 A
4 B
5 B
6 C
What I want:
type perc
A 0.5
B 0.33
C 0.17
We can write a simple query like this:
Select type, cnt/(select count(*) from product) AS perc
FROM (
select type, count(*) as cnt
from product
group by type
) nested
But vertica doesn't support the subselect which is not correlated
Need someone's help!
Vertica does support both correlated and non-correlated subquery even if you might have restrictions on the joining predicate.
So, your query here above just works. And - guess what - it continues to work even if you use indentation:
SQL> SELECT
type
, cnt/( select count (*) FROM product ) AS perc
FROM
( SELECT type, count (*) as cnt
FROM product
GROUP BY type
) nested ;
type | perc
------+----------------------
C | 0.166666666666666667
A | 0.500000000000000000
B | 0.333333333333333333
(3 rows)
Of course you can re-write it in a different way. For example:
SQL> SELECT
a.type
, a.cnt/b.tot as perc
FROM
( SELECT type , count (*) as cnt
FROM product
GROUP BY type ) a
CROSS JOIN
( SELECT count (*) AS tot
FROM product ) b
ORDER BY 1
;
type | perc
------+----------------------
A | 0.500000000000000000
B | 0.333333333333333333
C | 0.166666666666666667
(3 rows)
You could also use analytic functions, which are messy in this application, but work:
WITH product AS (
select 1 as productId, 'A' as type
union all select 2, 'A'
union all select 3, 'A'
union all select 4, 'B'
union all select 5, 'B'
union all select 6, 'C'
)
SELECT distinct /* distinct because analytic functions don't reduce row count like aggregate functions */
type, count(*) over (partition by type) / count(*) over ()
FROM product;
type | perc
------+----------------------
A | 0.500000000000000000
B | 0.333333333333333333
C | 0.166666666666666667
count(*) over (partition by type) counts each type;
count(*) over () counts over everything, so gets the total count