Divide COUNT Column By COUNT(DISTINCT(Column To give avg order size SQL SERVER - sql

Ok I have a list of the months orders so that bit is easy.
SELECT COUNT(*) AS ITEMS,
For the next part easy to:
COUNT(DISTINCT(PICKSET_NO))AS PICKSETS,
Its the next part I cant work out:
SUM(ITEMS/PICKSETS) AS AVGPICKSETSIZE
FROM dbo.orders
Thanks for your help on this. Here is the code in one block.
SELECT
COUNT(*) AS ITEMS,
COUNT(DISTINCT(PICKSET_NO))AS PICKSETS,
SUM(ITEMS/PICKSETS)
FROM dbo.CollationOrders
GO

Repeat the expression:
SELECT COUNT(*) AS ITEMS,
COUNT(DISTINCT PICKSET_NO) AS PICKSETS,
COUNT(*) / (1.0 * COUNT(DISTINCT PICKSET_NO))
FROM dbo.CollationOrders;
You can't re-use column aliases in the same select.
The 1.0 is to prevent integer division.

You may do like this:
SELECT ITEMS,
PICKSETS,
ITEMS / (1.0 * PICKSETS)
FROM (
SELECT COUNT(*) AS ITEMS,
COUNT(DISTINCT PICKSET_NO) AS PICKSETS
FROM TableName)t

I ended up using:
SELECT
COUNT(*) AS ITEMS,
COUNT(DISTINCT om.PicksetNo) AS PICKSETS ,
FORMAT(COUNT(*) / (1.0 * COUNT(DISTINCT om.PicksetNo)),'N2'),
ca.YWK AS YWK
FROM CHDS_Common.dbo.OMOrder om
INNER JOIN CHDS_Management.dbo.Calendar ca ON om.EarliestPickDate = ca.DT
GROUP BY ca.YWK

Related

How to calculate metrics between two tables

How to calculate metrics between two tables? In addition, I noticed that when using FROM tbl1, tbl2, there are noises, the WHERE filters did not work, a total count(*) was returned
Query:
select
count(*) filter(WHERE tb_get_gap.system in ('LINUX','UNIX')) as gaps,
SUM(CAST(srvs AS INT)) filter(WHERE tb_getcountsrvs.type = 'LZ') as total,
100 - (( gaps / total ) * 100)
FROM tb_get_gap, tb_getcountsrvs
Error:
SQL Error [42703]: ERROR: column "gaps" does not exist
I need to count in the tb_get_gap table by fields = ('LINUX', 'UNIX'), then a SUM ()in thesrvs field in the
tb_getcountsrvs table by fields = 'LZ' in type, right after
making this formula 100 - ((gaps / total) * 100)
It would seem that you cannot define gaps and also use it in the same query. In SQL Server you would have to use the logic twice. Maybe a subquery would work better.
select 100 - (t.gaps / t.total) * 100)
from
(
select
count(*) filter(WHERE tb_get_gap.system in ('LINUX','UNIX')) as gaps,
SUM(CAST(srvs AS INT)) filter(WHERE tb_getcountsrvs.type = 'LZ') as total
FROM tb_get_gap, tb_getcountsrvs
) t

SQL - Group by with having Result

For the following table i need to fetch user who did min 2 distinct transactions and have sum of net sale equal to or more than 20,
But, everything need to be in same select cant use temp table, i am using the below query, but getting ambiguity in result,
select z.customer_nbr, transaction_nbr
from sales_transaction,
(select customer_nbr
from sales_transaction
group by customer_nbr
having count(transaction_nbr) >=2) z
group by z.customer_nbr, transaction_nbr
having sum(net_sales_rtl)>20
Below is the result
Result ambiguity - customer_numer have no transaction with no 16
By "user", I assume you mean the entity referred to by customer_nbr.
Your query is only looking at the net sales for a single transaction, not for the entire customer.
You seem to want aggregation and having:
select st.customer_nbr
from sales_transaction st
group by st.customer_nbr
having count(distinct st.transaction_nbr) >= 2 and
sum(st.net_sales) > 20;
If you wanted all transactions to follow the 20 minimum, then two levels of aggregation would be appropriate:
select ct.customer_nbr
from (select st.customer_nbr, st.transaction_nbr,
sum(st.net_sales) as transaction_net_sales
from sales_transaction st
group by st.customer_nbr, st.transaction_nbr
) ct
group by ct.customer_nbr
having count(*) >= 2 and
min(ct.transaction_net_sales) > 20;
I think what is missing here is a join between the results from sales_transaction and the subquery z.
Considering both your tables share column transaction_nbr, you could have something like this:
select z.customer_nbr, s.transaction_nbr
from sales_transaction s,
(select customer_nbr, transaction_nbr
from sales_transaction
group by customer_nbr, transaction_nbr
having count(transaction_nbr) >=2) z
where z.transaction_nbr = s.transaction_nbr
group by z.customer_nbr, transaction_nbr
having sum(net_sales_rtl)>20

query the percentage of occurrences in an SQL table

I have a table of names, where each row has the columns name, and occurrences.
I'd like to calculate the percentage of a certain name from the table.
How can I do that in one query?
You can get it by using SUM(occurrences):
select
name,
100.0 * sum(occurrences) / (select sum(occurrences) from users) as percentage
from
users
where name = 'Bob'
Try this:
SELECT name, cast(sum(occurance) as float) /
(select sum(occurance) from test) * 100 percentage FROM test
where name like '%dog%'
Demo here
It is not very elegant due to the subquery in the field list but this will do the job if you want it in one query:
SELECT
`name`,
(CAST(SUM(`occurance`) AS DOUBLE)/CAST((SELECT SUM(`occurance`) FROM `user`) AS DOUBLE)) as `percent`
FROM
`user`
WHERE
`name`='miroslav';
Example Fiddle
Hope this helps,
I think conditional aggregation is the best approach:
select sum(case when name = #name then occurrences else 0 end) / sum(occurrences) as ratio
from t;
If you want an actual percentage between 0 and 100 multiply by 100.

How to get a percentile rank based on a computation

there are four tables as :
T_SALES has columns like
CUST_KEY,
ITEM_KEY,
SALE_DATE,
SALES_DLR_SALES_QTY,
ORDER_QTY.
T_CUST has columns like
CUST_KEY,
CUST_NUM,
PEER_GRP_ID
T_PEER_GRP has columns like
PEER_GRP_ID,
PEER_GRP_DESC,
PRNT_PEER_GRP_ID
T_PRNT_PEEER has columns like
PRNT_PEER_GRP_ID,
PRNT_PEER_DESC
Now for the above tables, i need to generate a percentile rank of the customer based on the computation fillrate = SALES_QTY / ORDER_QTY * 100 by peer group within a parent peer.
could someone please help on this?
You can use the analytic function PERCENT_RANK() to calculate the percentile rank, as below:
SELECT
t_s.cust_key,
t_c.cust_num,
PERCENT_RANK() OVER (ORDER BY (t_s.SALES_DLR_SALES_QTY / ORDER_QTY) DESC) as pr
FROM t_sales t_s
INNER JOIN t_cust t_c ON t_s.cust_key = t_c.cust_key
ORDER BY pr;
Reference:
PERCENT_RANK on Oracle® Database SQL Reference
If by "percentile rank" you mean "percent rank" (documented here), then the harder part is the joins. I think this is the basic data that you want for the percentile rank:
select t.PEER_GRP_ID, t.PRNT_PEER_GRP_ID,
sum(SALES_DLR_SALES_QTY * ORDER_QTY) as total
from t_sales s join
t_customers c
on s.CUST_KEY = c.cust_key join
t_peer_grp t
on t.PEER_GRP_ID = c.PEER_GRP_ID
group by t.PEER_GRP_ID, t.PRNT_PEER_GRP_ID;
You can then calculate the percentile (0 to 100) as:
select t.PEER_GRP_ID, t.PRNT_PEER_GRP_ID,
sum(SALES_DLR_SALES_QTY * ORDER_QTY) as total,
percentile_rank() over (partition by t.PRNT_PEER_GRP_ID
order by sum(SALES_DLR_SALES_QTY * ORDER_QTY)
)
from t_sales s join
t_customers c
on s.CUST_KEY = c.cust_key join
t_peer_grp t
on t.PEER_GRP_ID = c.PEER_GRP_ID
group by t.PEER_GRP_ID, t.PRNT_PEER_GRP_ID;
Note that this mixes analytic functions with aggregation functions. This can look awkward when you first learn about it.

How do I get the top 10 results of a query?

I have a postgresql query like this:
with r as (
select
1 as reason_type_id,
rarreason as reason_id,
count(*) over() count_all
from
workorderlines
where
rarreason != 0
and finalinsdate >= '2012-12-01'
)
select
r.reason_id,
rt.desc,
count(r.reason_id) as num,
round((count(r.reason_id)::float / (select count(*) as total from r) * 100.0)::numeric, 2) as pct
from r
left outer join
rtreasons as rt
on
r.reason_id = rt.rtreason
and r.reason_type_id = rt.rtreasontype
group by
r.reason_id,
rt.desc
order by r.reason_id asc
This returns a table of results with 4 columns: the reason id, the description associated with that reason id, the number of entries having that reason id, and the percent of the total that number represents.
This table looks like this:
What I would like to do is only display the top 10 results based off the total number of entries having a reason id. However, whatever is leftover, I would like to compile into another row with a description called "Other". How would I do this?
with r2 as (
...everything before the select list...
dense_rank() over(order by pct) cause_rank
...the rest of your query...
)
select * from r2 where cause_rank < 11
union
select
NULL as reason_id,
'Other' as desc,
sum(r2.num) over() as num,
sum(r2.pct) over() as pct,
11 as cause_rank
from r2
where cause_rank >= 11
As said above Limit and for the skipping and getting the rest use offset... Try This Site
Not sure about Postgre but SELECT TOP 10... should do the trick if you sort correctly
However about the second part: You might use a Right Join for this. Join the TOP 10 Result with the whole table data and use only the records not appearing on the left side. If you calculate the sum of those you should get your "Sum of the rest" result.
I assume that vw_my_top_10 is the view showing you the top 10 records. vw_all_records shows all records (including the top 10).
Like this:
SELECT SUM(a_field)
FROM vw_my_top_10
RIGHT JOIN vw_all_records
ON (vw_my_top_10.Key = vw_all_records.Key)
WHERE vw_my_top_10.Key IS NULL