How to multiply only one row in a query? - mysql

SELECT user_id, currency, SUM( price ) AS totalPrice, created
FROM accounts WHERE user_id IN ( SELECT users.id FROM users
WHERE country_id ='$con_id' )
AND created BETWEEN '2013-02-01' AND '2013-02-28' GROUP BY currency
This query give me result like
Curreny totalPrice
SEK 10
USD 10
I want to multiply only SEK from 7. I have only USD rate in the database, so i want to multiply it in the query with 7 to get SEK rate. How can I do that in this query?

Your question is a little bit confusing. If I understand your question correctly, you want to multiply the value of total value by 7 if the currency is equal to SEK.
SELECT user_id,
currency,
SUM(price) * IF(currency = 'SEK', 7, 1) totalPrice,
created
FROM accounts
WHERE user_id
IN
(
SELECT users.id
FROM users
WHERE country_id = '$con_id'
) AND
created BETWEEN '2013-02-01' AND '2013-02-28'
GROUP BY currency

I would store all conversion rates in a table. For SEK you store 7.0 als conversion rate and vor USD 1.0. Simply multiplie the totalPrice with the conversion rate (with sub query)

Here is an ugly way to implement it:
SELECT user_id, currency,
CASE WHEN currency = 'SEK' THEN SUM(price)*7
ELSE SUM(price) END totalPrice, created
FROM accounts
WHERE user_id
IN ( SELECT users.id FROM users
WHERE country_id = '$con_id')
AND created BETWEEN '2013-02-01' AND '2013-02-28'
GROUP BY currency

Related

MYSQL Recursive query with conditions

I have 2 tables,
the first table contains id_product, its rate and its price.
ID_product
rate
Price
1
TSA1
0.12
2
TSA1
1.5
1
TSA2
0.14
2
TSA2
1.7
1
TSA3
NULL
2
TSA3
1.7
1
TASM4
1.68
I have an other table which contains a rate and its rate destination if the price for its rate is NULL. Its for always has a price for each product. Here for example, the product 1 doesnt have a price for the rate TSA3. The correspondance table says that if it doesnt have a price for this rate, use the price of TASM4.
Origin_rate
Destination_rate
TSA1
TAS2
TSA2
TAS3
TSA3
TASM4
So, How can I complete my first table? I think, i need a recursive query, but i dont know how to do it in SQL.
This query gets you the price hirarchically:
with recursive cte(id_product, rate, price, origin_rate) as
(
select id_product, rate, price, rate
from mytable
union all
select cte.id_product, cte.rate, t.price, t.rate
from cte
join map on map.origin_rate = cte.origin_rate
left join mytable t on t.id_product = cte.id_product
and t.rate = map.destination_rate
where cte.price is null
)
select id_product, rate, price
from cte
where price is not null
order by id_product, rate;

I Need help in writing a multi-level ms access subquery

I am having hard time to wrap my mind around a multi-level query/sub-query. In short, I a table called REGISTER with 3 fields in it: TransactionId (PK), TransDate (DateTime), Amount (Currency). I need a single query to retrieve the TransactionId where TransDate is the Max and the Amount is the Min qualifying records. For example, if the max of qualifying record returns 5 records with today's date (any future dates is excluded), I would like to know the TransactionId of the lowest Amount within the 5 records returned.
I amble to accomplish this task with two separate query but I am sure it cab be done with a single one.
Query 1 (qryFlag):
SELECT REGISTER.TransDate, REGISTER.*
FROM REGISTER
WHERE (((REGISTER.TransDate)=(
SELECT Max(t2.Transdate) from REGISTER t2
where Transdate <= Date())));
Query 2:
SELECT REGISTER.TransactionId
FROM qryFlag INNER JOIN REGISTER ON qryFlag.TransactionId = REGISTER.TransactionId
WHERE (((qryFlag.Amount)=(SELECT Min(t2.Amount) from qryFlag t2)));
Try:
SELECT TOP 1 VTID.TransactionID
FROM (
SELECT TransactionID, Amount
FROM Register
WHERE TransDate = (SELECT Max(R.TransDate) FROM Register as R WHERE R.TransDate <= Date())
) as VTID
ORDER BY VTID.Amount
HTH
Dale
You need to GROUP BY TransDate to get the min amount and then join to the table:
SELECT r.*
FROM REGISTER AS r INNER JOIN (
SELECT TransDate, MIN(Amount) AS MinAmount
FROM REGISTER
WHERE TransDate = (SELECT Max(Transdate) FROM REGISTER WHERE Transdate <= Date())
GROUP BY TransDate
) AS g on g.TransDate = r.TransDate AND g.MinAmount = r.Amount

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

GROUP BY select within SELECT

I have one table which i want to select some rows and group them by date. the problem is when i'm selecting within my select that row appear to not grouped by date, see the example:
SELECT date, SUM(price), (SELECT SUM(price), date FROM expense WHERE
user = 'Catherine') as cprice FROM expense GROUP BY date
it does not grouping cprice, it will sum all Catherine prices and doesn't group it by date, by the way I tried GROUP BY date into the within select but doesn't work either.Any suggestion?
expense table:
id user price date
1 Frank 20 2014
2 Catherine 10 2013
3 Catherine 20 2014
thank you
You can try this:
SELECT
date,
SUM(price) as totalPrice,
SUM(IF(user='Catherine', price, 0)) as cprice
FROM expense
GROUP BY date
If you want both price together then you can try this:
SELECT
date,
SUM(price) + SUM(IF(user='Catherine', price, 0)) as cprice
FROM expense
GROUP BY date
try this query, it select * row where user = 'Catherine' and groups them by date
SELECT
date,
SUM(price)
FROM expense
WHERE user = 'Catherine'
GROUP BY date
Try Using Case Statement:(I'm Not Familiar With MySQL :( )
Not Sure,Like:
SELECT
date,
SUM(price) as totalPrice,
SUM(Case When user='Catherine' Then price Else 0 End CASE;) as catherine_price
FROM expense
GROUP BY date
You probaby can solve it using a two selects and pull out the data you need using a loop.

SQL query: calculate profile or loss in given 2 tables

I have 2 tables storing income:
id name date price isDel
1 abc 2012-01-26 613.90 0
2 cde 2012-01-25 530.10 0
and expenses:
id name price date isDel
1 b1 334.90 2012-01-26 0
2 b1 41.90 2012-01-25 0
3 d1 61.90 2012-01-25 0
I would like to get the result as follows:
date total income total expense profile n loss
2012-01-25 530.10 103.80 426.30
2012-01-26 613.90 344.90 26.90
Thanks. Can anyone provide SQL solutions? I did refer some member's question and answer at stackoverflow but I can't modify to want I need. Please help.
Provided you want profit/loss per day this should do:
SELECT Inc.date, TotalInc, TotalExp, TotalInc - TotalExp AS ProfitNLoss
FROM
(
SELECT date, SUM(price) as TotalInc
FROM Income
WHERE isdel = 0
GROUP BY date) as Inc
LEFT OUTER JOIN
(
SELECT date, SUM(price) as TotalExp
FROM Expense
WHERE isdel = 0
GROUP BY date) as Exp
ON Inc.date = Exp.date
UNION
SELECT Exp.date, TotalInc, TotalExp, TotalInc - TotalExp AS ProfitNLoss
FROM
(
SELECT date, SUM(price) as TotalInc
FROM Income
WHERE isdel = 0
GROUP BY date) as Inc
RIGHT OUTER JOIN
(
SELECT date, SUM(price) as TotalExp
FROM Expense
WHERE isdel = 0
GROUP BY date) as Exp
ON Inc.date = Exp.date
Argh, this is "give me the codes" question, but I'll give you few hints:
mySQL GROUP BY tutorial
mySQL GRUOP BY aggregate functions
mySQL subqueries
So what you need to do:
Create list of all unique dates (unfortunately I haven't find a way to generate list of dates within sql without table query or without long php array, if anyone knows a way to do this I'll be glad to add it to anser), so you will have to do this:
SELECT date FROM income GROUP BY date;
-- If there's a chance that you'll have record in expenses and not in income:
(SELECT date FROM income GROUP BY date)
UNION (SELECT date FROM expenses GROUP BY date;)
GROUP BY date;
-- Or create table containing just list of all dates (best option)
And than join all unique dates with expenses and income:
SELECT SUM(expenses.price) AS expenses, SUM(incomes.price) AS income, dates.date
FROM unique_dates -- or from your subquery
LEFT JOIN incomes ON incomes.date = unique_dates.date
LEFT JOIN expenses ON expenses.date = unique_dates.date
GROUP BY unique_dates.date
Oh and I have no idea what does profile n loss mean.
Thanks to Pheiberg and appreciated for your prof reply.
I just did some little change so it will return 0 when table has no record or return NULL, So that Profit calculation still able to cal even given -ve value. Here the code share to u guys.
note: im using MySQL
SELECT Inc.create_dt, IFNULL(TotalInc,0), IFNULL(TotalExp,0), IFNULL(TotalInc,0) - IFNULL(TotalExp,0) AS ProfitNLoss
FROM
(
SELECT create_dt, SUM(price) as TotalInc
FROM income
WHERE IsDel= 0
GROUP BY create_dt) as Inc
LEFT OUTER JOIN
(
SELECT create_dt, SUM(price) as TotalExp
FROM expenses
WHERE IsDel= 0
GROUP BY create_dt) as Exp
ON Inc.create_dt= Exp.create_dt
UNION
SELECT Exp.create_dt, IFNULL(TotalInc,0), IFNULL(TotalExp,0), IFNULL(TotalInc,0) - IFNULL(TotalExp,0) AS ProfitNLoss
FROM
(
SELECT create_dt, SUM(price) as TotalInc
FROM income
WHERE IsDel= 0
GROUP BY create_dt) as Inc
RIGHT OUTER JOIN
(
SELECT create_dt, SUM(price) as TotalExp
FROM expenses
WHERE IsDel= 0
GROUP BY create_dt) as Exp
ON Inc.create_dt= Exp.create_dt