Filling a field inside a select stamenet - MySQL - mysql

I'm trying to do calculations and fill a field inside a select statement. It looks like this:
CREATE VIEW SALES_REPORT AS(
SELECT
INVOICENO,
INVOICEDATE,
CLIENTID,
CONTACT,
INVOICEJOBNO,
ADDCHARGES,
CHARGESINFO,
EMPLOYEEID,
USUALPAY,
VAT,
SUBTOTAL (SELECT(USUALPAY * COUNT(*) AS SUBTOTAL FROM SALES_REPORT)),
TOTAL = (SUBTOTAL * VAT)
FROM SALES_REPORT_JOINS_CONFIG
GROUP BY INVOICENO ORDER BY INVOICEDATE DESC);
Any help would be great, thanks!

TOTAL = (SUBTOTAL * VAT)
should probably be
(SUBTOTAL * VAT) AS TOTAL
right now it's going to return the boolean true/false result of an equality comparison. You're NOT assigning the multiplication results to a 'total' field - you're comparing whatever value is in total to the result of the multiplication.
and this is a flat-out syntax error:
SUBTOTAL (SELECT(USUALPAY * COUNT(*) AS SUBTOTAL FROM SALES_REPORT)),

Related

How to multiply two columns and add a new column to the database?

Which customer id bought maximum products? (hint : get sales by multiplying product_quantity and price_per_item fields)
SELECT
customerid,
product_quantity * price_per_item as "sales",
SUM(sales)
FROM questions
GROUP BY customerid
This is how the database looks like
After adding the sales column I am not able to perform the sum operation and getting the following error:
SELECT customerid, product_quantity * price_per_item as "sales", SUM(sales) FROM questions GROUP BY customerid LIMIT 0, 1000
Error Code: 1054. Unknown column 'sales' in 'field list'
Desired output
The exact error you are seeing is due to the product expression not appearing directly inside an aggregated function. You should have taken the sum of this product directly. You might be fine just using the following LIMIT query:
SELECT customerid
FROM questions
GROUP BY customerid
ORDER BY SUM(product_quantity * price_per_item) DESC
LIMIT 1;
If there could be multiple customers tied for top sales, then use:
SELECT customerid
FROM questions
GROUP BY customerid
HAVING SUM(product_quantity * price_per_item) = (
SELECT SUM(product_quantity * price_per_item)
FROM questions
GROUP BY customerid
ORDER BY SUM(product_quantity * price_per_item) DESC
LIMIT 1
);
You cannot use an alias created in a select clause in the same select clause, because the expressions have no order. This means, that product_quantity * price_per_item as "sales" is not necessarily executed before SUM(sales), so the DBMS tells you that sales is unknown.
You don't need the alias anyway, because with one result row per customer, what amount other than the sum would you want to show?
SELECT
customerid,
SUM(product_quantity * price_per_item) AS sales
FROM questions
GROUP BY customerid
ORDER BY customerid;
This doesn't get you the top customer, though. But your query didn't either :-) This is just an explanation what's wrong in your original query.
Here are two options on how to build up on this to get the top customer(s):
Option 1 with a subquery (a CTE here):
WITH list AS
(
SELECT
customerid,
SUM(product_quantity * price_per_item) AS sales
FROM questions
GROUP BY customerid
)
SELECT *
FROM list
WHERE sales = (SELECT MAX(sales) FROM list);
Option 2 with an analytic function:
SELECT customerid, sales
FROM
(
SELECT
customerid,
SUM(product_quantity * price_per_item) AS sales,
MAX(SUM(product_quantity * price_per_item)) OVER() AS max_sales
FROM questions
GROUP BY customerid
) with_max
WHERE sales = max_sales;

MYSQL Calculate Conversion Rate

I could manage to return the correct Conversion Rate with this query:
SELECT
date(ordertime),
(count(*) / (
SELECT
sum(uniquevisits)
FROM
s_statistics_visitors
WHERE
datum = '2020-11-25') * 100) AS 'CONVERSION RATE'
FROM
s_order
WHERE
date(ordertime) = '2020-11-25'
AND subshopID = 1
GROUP BY
date(ordertime);
But it only returns the CR for one specific date. It wont work with the between keyword.
The subquery returns more then one result, if I delete the where condition in the subquery.
Schema for s_statistics: id, shopID, datum, uniquevisits, devicetype
Schema for s_order: id, ordernumber, ordertime, shopID
Since s_statistics saves values for each devicetype I have to sum uniquevisits per day. But the group by date(ordertime) at the end of my query does not affect the subquery.
-original post-
I want to calculate the conversion rate for an onlineshop.
The data is held in two tables.
Schema1 statistics: id / shopID / datum(yyyy-mm-dd) / uniquevisits / devicetype
Schema2 order: id / ordernumber / ordertime (YYYY-MM-DD HH-MM-SS)
Upon my knowledge the conversionrate calculates like:
(unique visits per day / 1000) * orders per day
I tried something like this:
SELECT
((count(ordernumber) / 1000) * (select sum(s_statistics_visitors.uniquevisits)
FROM s_statistics_visitors GROUP BY* datum))
FROM s_order where subshopID= '1'
GROUP BY date_format(ordertime, '%d%m%y')
ORDER BY date_format(ordertime, '%d%m%y')
I know that my query wont work - since there is no join - but I believe it might be the right approach. I could you join on the the date.
The problem:
the dateformat in the table: s_statistics_visitors is YYYY-MM-DD
and in order: YYYY-MM-DD HH-MM-SS
You seem to want something like this:
SELECT sv.datum, sv.shopId, count(*) as num_orders,
(count(*) / 1000) / sv.uniquevisits)
FROM s_order o JOIN
s_statistics_visitors sv
ON sv.datum = DATE(o.ordertime) AND
sv.shopId = o.shopId
GROUP BY sv.datum, sv.shopId, sv.uniqevisits ;
Note: This assumes that shopId is in both tables -- which makes sense for how you have described the problem. If not, you can adjust the shop id logic.

Apply group by on result of window function

I used window function to calculate each product's profit percentage
SELECT
productCode, productProfit, paymentDate, productName,
productProfit/sum(productProfit) OVER (PARTITION BY productCode) AS percent
FROM
profit;
The output
The next step, I want to calculate AVG(percent). How can I it into the first statement?
The result will look like this
Your way of calculating percent is bit weird. It seems that you are identifying contribution of particular transaction in overall profit.
Anyways, you can simply use your existing query's result-set as a Derived Table, and do a Group By using Year() function, to calculate the Avg():
SELECT
YEAR(dt.paymentDate) AS payment_date_year,
AVG(dt.percent) AS average_profit_percent
FROM
(
SELECT
productCode,
productProfit,
paymentDate,
productName,
productProfit/sum(productProfit) OVER (PARTITION BY productCode) AS percent
FROM
profit
) AS dt
GROUP BY
payment_date_year

How to combine two sql expressions into one?

I have the following issue:
It is necessary to write a query that will output 'item_id', 'price_in_byr'.
'price_in_byr' is calculated as the 'price' of the items table multiplied by the currency rate at the maximum date of the rate from the table rates.
See Schema
I apologize for my English, I'll try to explain by example:
Goods with item_id = 5 costs 20 euros, in the rates table the maximum date for the euro is January 12, at that date the exchange rate was 25. Total our 'price_in_byr' is 25 * 20 = 500
My solution with temp table:
CREATE TABLE tempRate SELECT currency, MAX(rate) AS maxRate FROM rates GROUP
BY currency;
SELECT items.item_id,(ifnull(tempRate.maxRate,1) * items.price) AS price_in_byr
FROM items
LEFT JOIN tempRate ON items.currency = tempRate.currency;
Tell me please, how can I do it in one query?
You can just use a subquery:
SELECT
items.item_id,(ifnull(tempRate.maxRate,1) * items.price) AS price_in_byr
FROM
items
LEFT JOIN
(
SELECT
currency, MAX(rate) AS maxRate
FROM
rates
GROUP BY
currency
) AS tempRate
ON items.currency = tempRate.currency;
In practice, you substitute "tempRate" by (definition of tempRate) AS tempRate.
You can see an example at dbfiddle here
If you actually want the * most_recent_rate*, you'd do something completely different; insert a subquery to compute it. This subquery looks for all rates of the given currency, sorts them by their exchange_ts (meaning timestamp) in descending order, and just picks to top 1:
SELECT
items.item_id,(ifnull(
(
SELECT
rate AS most_recent_rate
FROM
rates
WHERE
rates.currency = items.currency
ORDER BY
exchange_ts DESC
LIMIT 1
)
, 1) * items.price) AS price_in_byr
FROM
items ;
dbfiddle here
You can make your tempRate query into a subquery:
SELECT
items.item_id,
(ifnull(tempRate.maxRate,1) * items.price) AS price_in_byr
FROM
items
LEFT JOIN (
SELECT currency, MAX(rate) AS maxRate
FROM rates
GROUP BY currency
) as tempRate ON items.currency = tempRate.currency;
I am not sure if mysql supports this level of subquery but see if it works:
select I.item_id, I.price * CR.rt
from
items as I,
(
select r.currency cy, r.rate rt
from
rates as r, (select currency, max(date) max_date from rates group by currency) as R_MAXDATES
where
r.currency = R_MAXDATES.currency
and r.date = R_MAXDATES.max_date;
) As CR
where
I.currency = CR.cy

Calculating the sum of quantity * unit price in mysql

I think I'm missing a simple step here but I can't seem to figure it out. I've read the other threads and they talk about grouping but I can't seem to put it all together right.
I have a simple table that holds inventory transactions. In each row, there is a quantity and a price. I want to get the sum of the quantity and the sum of the each price * each quantity.
Here's my query. If I remove the grouping, I get 1 result that is multiplied by the number of rows in the table. If I add the grouping, I get the correct result multiple times. Am I missing something here? I just feel like running a query to get 20k results when they all contain the same data would be pointless.
SELECT (SUM(i.quantity) - IFNULL(SUM(s.quantity), 0)) AS quantity,
SUM(i.unitprice * i.quantity) AS totalprice
FROM 02_01_transactions t
LEFT JOIN 02_01_transactions i
ON i.type = 1
AND i.active = 1
LEFT JOIN 02_01_transactions s
ON s.type = 2
AND s.active =1
GROUP BY t.id
Not sure there is a need for the joins (you are not joining on any common value) or the type = 2 rows if you are just subtracting them out. Is there a reason the following does not work?
-- Total quantity, total price of all type 1, active transactions.
SELECT SUM(quantity) AS quantity,
SUM(unitprice * quantity) AS totalprice
FROM 02_01_transactions
WHERE type = 1
AND active = 1
Here's my guess at what you were trying to accomplish:
select
sum(quantity * case type when 1 then 1 when 2 then -1 end) as quantity,
sum(unitprice * quantity) as totalprice
from 02_01_transactions
where type in (1, 2) and active = 1