Coldfusion Calculate Sum Total (Loop? ) - sql

ok. so i have this table:
|item| quantity| price|
|apple | 2 | 2.00 |
|orange | 3 | 1.50 |
|grape | 5 | 2.50 |
i want to display the Grand Total that a customer has to pay.
how to do that? enter code here
i don't really know how to use array. can anyone show me how?
my code (sort of)
the price is shown in each of the row using this query:
<cfquery name="getPrice" datasource="fruits">
select *
from fruits
</cfquery>
<cfloop query="getPrice">
#quantity# | #price# | #totalPrice#
</cfloop><br>
the Grand Total should be displayed in the last row (Grand Total =$ 21.00 ).
Thanks for your help.

<cfset grandTotal = 0 />
<cfloop query="getPrice">
#quantity# | #price# | #totalPrice#<br />
<cfset grandTotal = grandTotal + ( price * quantity ) />
</cfloop>
<br /><br />
<cfoutput>#grandTotal#</cfoutput>

If ALL you want is the grand total, you can do that in SQL without looping over the records as:
<cfquery name="getPrice" datasource="fruits">
select sum(price*quantity) as grandTotal
from fruits
</cfquery>
Total: <cfoutput>#getPrice.grandTotal#</cfoutput>

Related

Finding products that were ordered 20% more times than the average of all other products in postgresql

I have asked a similar question and have received some help from some very nice people.
How to find the average of all other products in postgresql.
This question is not all but I thought I can work out the rest on my own if the hardest part can be resolved but apparently I've overestimated my abilities. So I'm posting another question... :)
The question is as followed.
I have a table Products which looks like the following:
+-----------+-----------+----------+
|ProductCode|ProductType| .... |
+-----------+-----------+----------+
| ref01 | BOOKS | .... |
| ref02 | ALBUMS | .... |
| ref06 | BOOKS | .... |
| ref04 | BOOKS | .... |
| ref07 | ALBUMS | .... |
| ref10 | TOYS | .... |
| ref13 | TOYS | .... |
| ref09 | ALBUMS | .... |
| ref29 | TOYS | .... |
| ref02 | ALBUMS | .... |
| ..... | ..... | .... |
+-----------+-----------+----------+
Another table Sales which looks like the following:
+-----------+-----------+----------+
|ProductCode| qty | .... |
+-----------+-----------+----------+
| ref01 | 15 | .... |
| ref02 | 12 | .... |
| ref06 | 20 | .... |
| ref04 | 14 | .... |
| ref07 | 11 | .... |
| ref10 | 19 | .... |
| ref13 | 3 | .... |
| ref09 | 9 | .... |
| ref29 | 5 | .... |
| ref02 | 4 | .... |
| ..... | ..... | .... |
+-----------+-----------+----------+
I am trying to find the products that were ordered 20% more than the average of all other products of the same type.
A product can be ordered several times and the quantities (qty) of each order might not be the same. Such as ref02 in the sample table. I only included one example (ref02) but it is the case for all products. So to find how many times a specific product was ordered would mean to find the sum of quantities ordered from all orders of the product.
By manually calculating, the result should be something like:
+-----------+-----------+----------+
|ProductCode| qty | .... |
+-----------+-----------+----------+
| ref02 | 16 | .... |
| ref06 | 20 | .... |
| ref07 | 11 | .... |
| ref10 | 19 | .... |
| ..... | ..... | .... |
+-----------+-----------+----------+
So if looking in the type ALBUMS and product ref02, then I need to find the average of Orders of ALL OTHER ALBUMS.
In this case, it is the average of ref06 and ref04, but there are more in the actual table. So what I need to do is the following:
Since product ref02 is 'ALBUMS' and there are two orders of ref02, the total orders will be 12+4=16. And ref07 and ref09 are also 'ALBUMS'.
So their average is (11+9)/2=10 < 12+4=16.
Since product ref06 is 'BOOKS', and **ref01** and ref04 are also 'BOOKS'.
So their average is (15+14)/2=14.5 <20.
Since product ref07 is 'ALBUMS', and **ref02** and ref09 are also 'ALBUMS'.
So their average is (12+9+4)/3=8.3 <11.
Since product ref10 is 'TOYS', and ref13 and ref29 are also 'TOYS'
So their average is (3+5)/2=4<19.
The rest does not satisfy the condition thus will not be in the result.
I know how to and was able to find the average of orders for all products under the same type, but I have no idea how to find the average of orders for all other products under the same type.
I know how to find the desired products with the helps I've received from my previous question How to find the average of all other products in postgresql, but that is when there is only one order for each product. I don't know how to proceed if there are multiple orders for each product. This is the "overestimated" bit I've mentioned at the beginning... :(
The answers I've received in my previous question has this problem:
DEMO (db<>fiddle). The tables in the demo are much more similar to the ones I'm working with, and as you see, there are many rows for one product. (The duplicated rows are by accident. The values just happened to be the same)
I am using PostgreSQL, but the exercise forbids the use of several keywords including: WITH, OVER, LIMIT, PARTITION, or LATERAL. I realize that they are commonly used in most solutions I've found and the ones provided to me, but I cannot use them because no result will be returned otherwise... :(
I know not being allowed to use these keywords can be annoying, but I honestly don't know what to do so please help! :)
I wrote a query for all combinations, Total by Product Code, Total by Product Type and e.t.c. You can calculate the average value if you need using (SUM values / Count Values).
select
main1.product_code,
main1.product_type,
main1.total as "Total by Product Code",
main1.sales_count as "Count by Product Code",
main2.total as "Total by Product Type",
main2.sales_count as "Count by Product Type",
main2.total - main1.total as "Total by Other Products Types (ignore this Product Code)",
main2.sales_count - main1.sales_count as "Count by Other Products Types (ignore this Product Code)"
from
(
select
s.product_code,
p.product_type,
sum(s.qty) as total,
count(*) as sales_count
from
examples.sales s
left join
examples.products p on p.product_code = s.product_code
group by
s.product_code, p.product_type
) main1
left join
(
select t1.product_type, sum(t1.qty) as total, count(*) as sales_count from (
select * from examples.sales s
left join examples.products p on p.product_code = s.product_code
) t1
group by t1.product_type
) main2 on main1.product_type = main2.product_type
Result:
Pr.Code
Pr.Type
Total by Pr.Code
Count by Pr.Code
Total by Pr.Type
Count by Pr.Type (ignore this Product Code)
Total by Other Pr.Types
Count by Other Pr.Types (ignore this Product Code)
ref29
TOYS
5
1
27
3
22
2
ref06
BOOKS
20
1
34
2
14
1
ref13
TOYS
3
1
27
3
24
2
ref02
ALBUMS
16
2
36
4
20
2
ref10
TOYS
19
1
27
3
8
2
ref07
ALBUMS
11
1
36
4
25
3
ref04
BOOKS
14
1
34
2
20
1
ref09
ALBUMS
9
1
36
4
27
3
Fix two errors in the setup
1.
A product can be ordered several times ...
It should still appear once in the Products table. The 2nd entry of ref02 is wrong.
2.
So to find how many times a specific product was ordered would mean to find the sum of quantities ordered from all orders of the product.
So your rationale for ref07 doesn't hold:
Since product ref07 is 'ALBUMS', and **ref02** and ref09 are also 'ALBUMS'.
So their average is (12+9+4)/3=8.3 <11.
Counting the two sales for ref02 separately is wrong in light of your definition. Operate with sums per product:
Since product ref07 is 'ALBUMS', and ref02 and ref09 are also 'ALBUMS'.
So their average is (16+9)/2 = 12.5 > 11. -- doesn't qualify!
Answer
find the products that were ordered 20% more than the average of all other products of the same type.
I am putting a proper solution first: an efficient query for Postgres 11+ using a window function with custom window frame over the aggregate sum()
SELECT product_code, orders
FROM (
SELECT product_code, sum(s.orders) AS orders
, avg(sum(s.orders)) OVER (PARTITION BY p.product_type
ROWS BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING
EXCLUDE CURRENT ROW) AS avg_orders
FROM product p
JOIN sales s USING (product_code)
GROUP BY product_code, p.product_type
) sub
WHERE avg_orders * 1.2 < orders
ORDER BY product_code; -- optional
Result (with the errors mentioned above fixed):
product_code
orders
ref02
16
ref06
20
ref10
19
Much more efficient than the below.
Postgres can apply a window function over an aggregate in the same query level. See:
Postgres window function and group by exception
How to use a SQL window function to calculate a percentage of an aggregate
At your request, an inefficient solution working around modern SQL features:
SELECT product_code, ps.orders
FROM (
SELECT product_code, p.product_type, sum(s.orders) AS orders
FROM product p
JOIN sales s USING (product_code)
GROUP BY product_code, p.product_type
) ps
JOIN LATERAL (
SELECT avg(orders) AS avg_orders
FROM (
SELECT sum(s1.orders) AS orders
FROM product p1
JOIN sales s1 USING (product_code)
WHERE p1.product_type = ps.product_type
AND p1.product_code <> ps.product_code
GROUP BY product_code
) sub
) a ON a.avg_orders * 1.2 < ps.orders
ORDER BY product_code; -- optional
db<>fiddle here
Same result.
We have to repeat the basic aggregation for sums in the subquery, since we cannot use a CTE to materialize it. (Possible remaining workaround: use a temporary table isntead.)
Basics in my answer to your previous question:
How to find the average of all other products in postgresql

MS Access 2007 query pulls same records multiple times

I have a problem, my query in MS Access 2007 pulls same records multiple times.
There are two tables : sales, products
Product Table
ID | Name | Price | Code
01 | PEN | 0.10$ | 01
02 | ITEM | 0.20$ | 2567
Sales table:
ID | Code | Amount
1 | 01 | 4
2 | 2567 | 2
And there's query
SELECT Product.Name, Product.Price, Sales.Amount
FROM Product, Sales
WHERE Product.Code IN (SELECT Sales.Code FROM Sales);
Thats the result
Name Price Amount
PEN $0.10 4
PEN $0.10 4
ITEM $0.20 2
ITEM $0.20 2
Change your query to
SELECT Product.Name, Product.Price, Product.Amount
FROM Product, Sales
WHERE Product.Code = Sales.Code;
Your query is currently joining every record in Product to every record in Sales, resulting in multiples. You need to do a join between them, either in the WHERE clause like Yousaf suggested, or like this, which is more the standard way to do it:
SELECT Product.Name, Product.Price, Sales.Amount
FROM Product
INNER JOIN Sales ON Product.Code = Sales.Code

Access SQL query update calculation for duplicates

I have a query that filters results for products which have had orders sent after an user-input date, and calculates what the quantity becomes if the order was sent after that date.
SELECT *, [OnHand]+[OrderJoin.Quantity] AS Qty After
FROM Query3
WHERE (((Query3.ShippedDate)>[Enter End Date] And (Query3.ShippedDate) Is Not Null));
However, I need a way for it to recognise duplicates and update it based on those.
e.g. I have this
ID | Product Name | Qty Before | Qty Shipped | Qty After
11 | Chocolate | 80 | 20 | 100
11 | Chocolate | 80 | 10 | 90
And I'd need a way for it to show Qty After as 110 (after the 10 and 20 shipped)
If I understand correctly, you want an aggregation query. This would be something like this:
SELECT id, ProductName,
OnHand]+ SUM([OrderJoin.Quantity]) AS Qty After
FROM Query3
WHERE Query3.ShippedDate > [Enter End Date] And
Query3.ShippedDate) Is Not Null
GROUP BY id, ProductName, OnHand;
I note that OrderJoin is not defined, but that is the structure of your original query.

How do I list my items by when they will be out of inventory

I have a table that lists items in my inventory, the total quantity on hand, order qty and ship date.
+-------+-----------+------------+----------+
| Items | QtyOnHand | QtyOrdered | ShipDate |
+-------+-----------+------------+----------+
| Itema | 100 | 80 | 3/4/14 |
| Itemb | 80 | 220 | 3/8/14 |
| Itema | 100 | 80 | 3/10/14 |
| Itemb | 80 | 100 | 3/12/14 |
+-------+-----------+------------+----------+
I would like a return like this that includes the item, date we are out of inventory and the amount over the inventory we are on that date.
Note: the same item is generally on the list multiple times and this is a representation of actual sales orders. The qty on hand number is the total on hand for that item TODAY and will be the same every time the item is listed.
My issue is that if item a ships 80 cases on 3/4/14 and has 100 on hand then with 20 left over the shipment of 80 cases on 3/10/14 will be 60 cases short so the query will return item a 3/10/14 -60. To indicate that based the current on hand values, on 3/10/14 item a will not have adequate inventory to cover the order.
Itemb 3/8/14 -140
Itema 3/10/14 -60
Any help would be greatly appreciated.
Ken
I think you may want something like this:
SELECT Items,ShipDate,(QtyOnHand-QtyOrdered)
from TableName
where (QtyOnHand-QtyOrdered) < 0
You haven't specified which DBMS you're using. MSSQL 2012 makes this fairly simple:
WITH cteInventory (Items, ShipDate, Stock) As
(
SELECT
Items,
ShipDate,
QtyOnHand - Sum(QtyOrdered) OVER (PARTITION BY Items ORDER BY ShipDate)
FROM
Inventory
)
SELECT
Items,
Min(ShipDate) As Date,
Max(Stock) As Stock
FROM
cteInventory
WHERE
Stock < 0
GROUP BY
Items
ORDER BY
Date
;
SQL Fiddle

Simply query with calculated fields

I have 2 tables in my sqlite3 database. Can someone help me with the sql command below:
tbltrans:
transid | transdate | discountpercentage | Bank
12345 10/09/2011 5 20.00
tbltrans2:
transid | itemnr |price | btwpercentage | qty
12345 205 10.11 12 5
12345 302 15.00 6 7
12345 501 20.00 21 3
SO I want to get a query table with total amount of sale for each transid's and calculated cash column, Like:
Select
Sum(tbltrans2.qty * tbltrans2.price) as TotalAmount,
(Totalamount - tbltrans.Bank) as Cash
where
tbltrans.transid = tbltrans2.transid and transdate = '10/09/12'
Can someone please correct this sql satement ?
Select
Sum(ifnull((tbltrans2.qty * tbltrans2.price),0))-tbltrans.Bank as cash
from tbltrans,tbltrans2
where
tbltrans.transid = tbltrans2.transid and tbltrans.transdate = '10/09/12'
group by tbltrans.transid
try this
If you want to select total amount also then include this in
select,
Sum(ifnull((tbltrans2.qty * tbltrans2.price),0)) as TotalAmount