SQL Server 2008 - Multiply 2 columns in SQL is not working - sql-server-2008

I am using a subquery to get column value and then multiply it with another column. but it gives error. Query is:
select
TotalCost, CurrencyType, b.TrxCurrency,
(select Rate
from CurrencyConversion
where FCurrencyType = a.CurrencyType
and TCurrencyType = b.TrxCurrency
and IsDelete = 0) as Rate,
(TotalCost * Rate) as NewRate
from
TB_Accom a
inner join
Agency b on a.AgencySysId = b.AgencySysId
where
b.AgencySysId = 62
and TotalCost != 0
And the error I get is:
Msg 207, Level 16, State 1, Line 3
Invalid column name 'Rate'

Related

SQL calculation based on different conditions

I have one table and trying to subtract the total where a condition is True from the full total.
Ticket
Amount
Code
11
5.00
12
3.00
X
13
10.00
14
2.00
X
My query was
SELECT SUM(AMOUNT)
FROM Table
MINUS
SELECT SUM(Amount)
FROM Table
WHERE Code = 'X'
So the answer should be 20 - 5= 15
Below two possible queries:
-- Use IF operator
SELECT SUM(amount) - SUM(IF(code = 'X', amount, 0)) FROM tbl;
-- Use implicit MySQL conversion boolean to int (true => 1)
SELECT SUM(amount) - SUM(amount * (code = 'X')) FROM tbl;
SQL editor online

Why does my SQL Statement not SUM() up correctly?

I have the following statement:
SELECT
ROUND(SUM(invoicetitle.unitpricegross*invoicetitle.suppliedquantity),2) as Costs,
SUM(invoicetitle.suppliedquantity) AS Unitamounts
FROM invoicetitle
WHERE
((SELECT invoice.state
FROM invoice where invoicetitle.invoiceid = invoice.invoiceid
and (invoice.invoicedate >= 1609459200000 and invoice.invoicedate <= 1640908800000)) = (1 or 4))
GROUP BY invoicetitle.invoicetitle_number
note that = (1 or 4) refers to two statements in the database where 1 is sold and 4 is a refund.
With = (1)) I get the following results:
Costs - Unitamounts
3.281,10 - 582
With = (4)) I get the following results:
Costs - Unitamounts
-115,2 - -32
With = (1 or 4)) I get the following results:
Costs - Unitamounts
3.281,10 - 582
But I expect as a correct SUM() of it:
Costs - Unitamounts
3.165,9 - 550
What am I doing wrong that the results are not subtracted correctly?
You probably meant to do:
SELECT
ROUND(SUM(invoicetitle.unitpricegross*invoicetitle.suppliedquantity),2) as Costs,
SUM(invoicetitle.suppliedquantity) AS Unitamounts
FROM invoicetitle
INNER JOIN invoice ON invoicetitle.invoiceid = invoice.invoiceid
and (invoice.invoicedate BETWEEN 1609459200000
and 1640908800000)
WHERE invoice.state IN (1,4)
GROUP BY invoicetitle.invoicetitle_number

How to get average value from another average using MySQL

I have a Table that stores subjects. Each subject has Papers say Paper 1,2,3... and each paper has several tests that are undertaken like say TEST 1, 2, 3 ..like that.
Now what I want is to get the Average of TESTS undertaken in a particular paper which I have managed to get as below in Average Mark column;
I need help on how to get the average of the paper taken like an average of Paper 1 and Paper 2. to be put in paper_avarage column which should, in this case, be 32.5 but I'm getting 30.00 which is wrong
This is my code sofar which is giving me the average that is slightly wrong.
SELECT SubjectCode
, PaperNo
, TestNo
, MarkScored
, AverageMark
, (SELECT avg(AverageMark) As avMark
FROM test_results
WHERE AdminNo = 'SPS-20-O-0003'
AND SubjectCode = 112
AND StudyYear = 2020
AND StudyTerm = 1
AND StudyClass = 1) as paper_average
FROM test_results
WHERE AdminNo = 'SPS-20-O-0003'
AND SubjectCode = 112
AND StudyYear = 2020
AND StudyTerm = 1
AND StudyClass = 1
ORDER
BY PaperNo ASC
Thanks for your help in advance.
You want an average of averages, so replace your subquery with this:
(
SELECT AVG(t.avMark) AS avMark
FROM (
SELECT AVG(AverageMark) AS avMark
FROM test_results
WHERE AdminNo = 'SPS-20-O-0003'
AND SubjectCode = 112
AND StudyYear = 2020
AND StudyTerm = 1
AND StudyClass = 1
GROUP BY PaperNo
) AS t
) AS paper_average

MySQL nested, nested subquery not getting outter variable

I have a spendings table and a dates table, that are joined by date_id and id...
What I'm trying to do, is get from 1 query all the info from spendings, plus the sum of all the spendings but with a limit and/or offset
This is the query right now
SELECT spendings.id, spendings.price, spendings.title,
dates.date, users.username, currencies.value,
( SELECT SUM(sum_table.price)
FROM (
SELECT s.price
FROM spendings s, dates d
WHERE s.date_id = d.id
AND day(d.date) = 25
LIMIT 2 OFFSET 0
) as sum_table
) AS sum_price
FROM spendings, dates, users, currencies
WHERE spendings.date_id = dates.id
AND day(dates.date) = 25
AND spendings.user_id = users.id
AND spendings.curr_id = currencies.id
LIMIT 2 OFFSET 0
Output
id price title date username value sum_price
3 6.00 title1 2013-11-25 alex € 21.00
4 15.00 title2 2013-11-25 alex € 21.00
It works, but only if the date here day(d.date) = 25 is the same as the outer one here day(dates.date) = 25
If instead I put day(d.date) = day(dates.date) which seems the logic thing to do, I get #1054 - Unknown column 'dates.date' in 'where clause'
If anyone has an idea to make this simpler let me know :)
Try to join instead of using nested correlated subqueries:
SELECT spendings.id, spendings.price, spendings.title,
dates.date, users.username, currencies.value,
y.sum_price
FROM spendings, dates, users, currencies
JOIN (
SELECT day, SUM(sum_table.price) As sum_price
FROM (
SELECT day(d.date) As day,
s.price
FROM spendings s, dates d
WHERE s.date_id = d.id
AND day(d.date) = 25
LIMIT 2 OFFSET 0
) sum_table
GROUP BY day
) y
ON y.day = day(dates.date)
WHERE spendings.date_id = dates.id
-- AND day(dates.date) = 25 <== commented since it's redundant now
AND spendings.user_id = users.id
AND spendings.curr_id = currencies.id
Some remarks:
Using old join syntax with commas is not recommended: FROM table1,table2,table2 WHERE
The recommended way of expressing joins is "new" ANSI SQL join syntax:
FROM table1
[left|right|cross|[full] outer|natural] JOIN table2 {ON|USING} join_condition1
[left|right|cross|[full] outer|natural] JOIN table3 {ON|USING} join_condition2
....
Actually this "new syntax" is quite old now, since is has been published, as I remember, in 1992 - 22 years ago. In IT industry 22 years is like 22 ages.

MySQL - Multiply column by value depending on that column

How can I write this.. I have table 'Company' with a column 'Size'. The size references enums. I need to display the average company size as alias AS 'AverageEstimatedCompanySize' by substituting column 'Size' when column 'Size' is:
1 = 15
2 = 30
3 = 50
4 = 100
5 = 250
In other words, my table shows company size as either 1, 2, 3, 4 or 5. While 1 is actually a company size of 15.
This is all part of a bigger query:
SELECT COUNT(DISTINCT(ID)) AS 'Total # of Opps', AVG(Size*?) AS 'AverageEstimatedCompanySize'
FROM persontable AS POJT INNER JOIN opportunity
ON POJT.ID = opportunity.id
WHERE opportunity.TimeStamp >= '2012-01-01' AND opportunity.TimeStamp <= '2012-12-31' AND POJT.JobTitleID IN
(SELECT Id
FROM job
WHERE CategoryID IN
(SELECT id
FROM job_category
WHERE name IN ('Sc', 'Ma', 'Co', 'En', 'Tr')))
Sounds like something solvable with a case statement. The following is untested but should point you in the right direction.
SELECT
COUNT(DISTINCT(ID)) AS 'Total # of Opps',
AVG(
CASE Size
WHEN 1 THEN 15
WHEN 2 THEN 30
WHEN 3 THEN 50
WHEN 4 THEN 100
WHEN 5 THEN 250
END
) AS 'AverageEstimatedCompanySize'
FROM persontable AS POJT INNER JOIN opportunity
ON POJT.ID = opportunity.id
WHERE opportunity.TimeStamp >= '2012-01-01' AND opportunity.TimeStamp <= '2012-12-31' AND POJT.JobTitleID IN
(SELECT Id
FROM job
WHERE CategoryID IN
(SELECT id
FROM job_category
WHERE name IN ('Sc', 'Ma', 'Co', 'En', 'Tr')))
I'm thinking that one approach might be to modify the query to JOIN to the Company table appropriately (that's something you'll need to work out), and then modify the AVG statement:
... AVG(CASE `Size`
WHEN 1 THEN 15
WHEN 2 THEN 30
WHEN 3 THEN 50
WHEN 4 THEN 100
WHEN 5 THEN 250 END) AS 'AverageEstimatedCompanySize'
where Size is from the Company table.
Now, a more dynamic approach would be to create a new field, or even a new table, that maps those sizes and just JOIN the Company table and say the new table in the query and just grab the appropriate field per row then. That would get rid of the CASE statement.