How to use FORMAT ( Employee.Salary,'C',EN-US) in SUM statement ? Getting error 'Conversion Failed - sql

I need to display 'tax wage' column in US $ format IN SQL using FORMAT function.
I am using Microsoft SQL server. Can someone please help?
Getting error:
"Conversion failed when converting the nvarchar value '$17,037.72' to data type int."
Below is the query I wrote:
SELECT EMPLOYEE.ID, EMPLOYEE.NAME, P.DEDCODE,
SUM(CASE WHEN P.DEDCODE ='SS2' THEN FORMAT(P.AMOUNT,'C','EN-US') ELSE 0 END) AS 'TAX WAGE'
FROM EMPLOYEE
JOIN P ON EMPLOYEE.ID = P.ID and EMPLOYEE.COMPANY = P.COMPANY
WHERE
P.DEDCODE ='SS2'
AND P.YEAR ='2018'
GROUP BY
EMPLOYEE.ID,
EMPLOYEE.NAME,
P.DEDCODE
I expect the tax wage column to have $70.5 as output instead of simple number 70.5

Your format function should be on SUM():
FORMAT(SUM(CASE WHEN P.DEDCODE = 'SS2' THEN P.AMOUNT ELSE 0 END),'C','EN-US') AS [TAX WAGE]
You already included WHERE clause with P.DEDCODE ='SS2' then why you need conditional aggregation, it should be only
SELECT . . . ,
FORMAT(SUM(P.DEDCODE),'C','EN-US') AS [TAX WAGE]
. . .

Related

Query for fuel usage with a subquery

Searched Stackoverflow, and was not able to find an answer to my question (maybe it's there, but did not see one).
Have the following query which lists the mileage used, fuel cost, and fuel quantity for multiple vehicles stored at a location in the MAIN table. Also have a sub-query to calculate the cost per mile - and in that subquery is a WHERE clause to not calculate unless the fuel_qty > 0 (cannot divide by zero, unless you are Chuck Norris - ha ha). Also need to display a zero for the fuel_qty (in line 3 of this query) if it is a zero value. Am getting an error with this query - saying that it is "not a single-group group function". Is there something which I am missing or not seeing?
Have tried adding cost_per_mile to the group by clause, but received an "invalid identifier" error. Then also added a group by clause to the subquery - but that also did not work.
select cost.mileage_useage
, cost.fuel_cost
, cost.fuel_qty
, (select (sum(cost1.mileage_usage / cost1.fuel_qty) * cost1.fuel_cost)
from cost cost1
where cost1.fuel_qty > 0) as cost_per_mile
from cost
inner join main on main.equip_no = cost.equip_no
where main.stored_loc = 4411
group by
cost.mileage_useage
, cost.fuel_cost
, cost.fuel_qty
Why doesn't this do what you want?
select c.mileage_useage, c.fuel_cost, c.fuel_qty,
(sum(c.mileage_usage) * c.fuel_cost /
nullif(c.fuel_qty, 0)
) as cost_per_mile
from cost c inner join
main m
on m.equip_no = c.equip_no
where main.stored_loc = 4411
group by c.mileage_useage, c.fuel_cost, c.fuel_qty
Believe I found an answer - thank you for all your help! This takes into consideration if the mileage useage = 0 or is a negative number. Also if the fuel quantity = 0 then that portion of the equation is not possible to divide by a zero value. It may look a little strange, but this works!
select cost.mileage_useage
, cost.fuel_cost
, cost.fuel_qty
, ( sum(((CASE WHEN cost.mileage_usage = 0 THEN 1
WHEN cost.mileage_usage < 0 THEN TO_NUMBER(NULL)
ELSE cost.mileage_usage END)
/ DECODE(eq_cost.fuel_qty,0, 1, eq_cost.fuel_qty))
* eq_cost.fuel_cost )) as cost_per_mile
from cost
inner join main on main.equip_no = cost.equip_no
where main.stored_loc = 4411
group by cost.mileage_useage
, cost.fuel_cost
, cost.fuel_qty
You can further simplify it as following:
select cost.mileage_useage
, cost.fuel_cost
, cost.fuel_qty
, sum((CASE WHEN cost.mileage_usage = 0 THEN eq_cost.fuel_cost
WHEN cost.mileage_usage > 0 THEN cost.mileage_usage * eq_cost.fuel_cost END)
/ (case when eq_cost.fuel_qty = 0 then 1 else eq_cost.fuel_qty end)) as cost_per_mile
from cost
inner join main on main.equip_no = cost.equip_no
where main.stored_loc = 4411
group by cost.mileage_useage
, cost.fuel_cost
, cost.fuel_qty;
Cheers!!

How to Group By in SQL Server Query

I'm using this query to get the Sum of SaleAmount for each type (SOType) of Sale Invoices.
I am getting the result but the result is not grouped by SOType. Have tried to use Group by Outside the query after where condition but getting an error as
"Column 'SaleInvoices.InvoiceID' is invalid because it is not
contained in either aggregate or group by function".
DECLARE #fromDate Datetime = '2019/05/23'
DECLARE #toDate Datetime = '2019/10/25'
DECLARE #isKpi int = '1'
SELECT (
(Select Sum((Isnull(I.Quantity,0)*Isnull(I.SalePrice,0))+((Isnull(I.Quantity,0)*Isnull(I.SalePrice,0) - I.Discount) *(I.TAX/100)))
from ItemsSold as I
where I.InvoiceId= S.InvoiceID and I.InvoiceType='Sale Invoice'
) -
(Select isnull(Sum((Isnull(I.Quantity,0)*Isnull(I.SalePrice,0))+((Isnull(I.Quantity,0)*Isnull(I.SalePrice,0) - I.Discount)*(I.TAX/100))),0)
from ItemsSold as I
where I.InvoiceId= S.InvoiceID and I.InvoiceType='Sale Return'
)) as Total
,S.SOType as SOType
FROM SaleInvoices AS S
where S.OrderDate>=Convert(VARCHAR,#fromDate,111) and S.OrderDate<=Convert(varchar,#toDate,111)
You want conditional aggregation. The logic should look something like this:
select s.SOType,
sum(case when i.invoicetype = 'Sale Invoice'
then (I.Quantity * I.SalePrice) * (1 - i.discount) * i.tax / 100.0
when i.invoicetype = 'Sale Return'
then - (I.Quantity * I.SalePrice) * (1 - i.discount) * i.tax / 100.0
end) as Total
from SaleInvoices s join
ItemsSold i
on i.InvoiceId= s.InvoiceID
where s.OrderDate >= #fromDate and
s.OrderDate <= #toDate
group by s.SOType ;
I'm not sure I got the arithmetic correct.
Notes:
The group by clause defines the rows being returned by the query. If you want one row per SOType then you want to GROUP BY SOType.
Use date comparisons and functions for dates. It is absurd to convert a date to a string to compare to a date.
You probably don't need COALESCE() or ISNULL() to handle NULL values. These are generally ignored by aggregation functions.

Getting percentages of counts in SQL Server

I am building an SQL Server query that gets the number of leads that were generated from a certain sources by month. This is the query that tells me the monthly count. But I want to add a column that shows what those leads are for that month as a total of all leads for that month. I'm not clear on how to do this. Any help?
SELECT FORMAT([ProspectData].[dbo].[Real Estate.KPC.Leads.2018-08-08].[Created Date]
, 'yyyy-MM') AS 'YYYY-MM'
, 'Kiosk-Mall' AS 'Lead Source'
, COUNT(*) AS 'Monthly Total From That Lead Source'
FROM [ProspectData].[dbo].[Real Estate.KPC.Leads.2018-08-08]
WHERE [ProspectData].[dbo].[Real Estate.KPC.Leads.2018-08-08].[Lead Source] =
'Kiosk-Mall'
GROUP BY FORMAT([ProspectData].[dbo].[Real Estate.KPC.Leads.2018-08-08].[Created Date], 'yyyy-MM')
ORDER BY FORMAT([ProspectData].[dbo].[Real Estate.KPC.Leads.2018-08-08].[Created Date], 'yyyy-MM');
You can use conditional aggregation -- basically moving the WHERE condition to a CASE expressions in the argument to an aggregation function:
SELECT FORMAT(l.[Created Date], 'yyyy-MM') AS YYYYMM,
'Kiosk-Mall' AS Lead_Source,
SUM(CASE WHEN l.[Lead Source] = 'Kiosk-Mall' THEN 1 ELSE 0 END) AS [Monthly Total From That Lead Source],
AVG(CASE WHEN l.[Lead Source] = 'Kiosk-Mall' THEN 1.0 ELSE 0 END) AS proportion_of_total
FROM [ProspectData].[dbo].[Real Estate.KPC.Leads.2018-08-08] l
GROUP BY FORMAT(l.[Created Date], 'yyyy-MM')
ORDER BY YYYYMM
Notes:
Table aliases make the query easier to write and to read.
It is better to choose column aliases that do not need to be escaped (i.e. no spaces, no punctuation).

SQL Query with between two dates showing even those not between

select ktl.id, kth.trans_dte, kth.trtype, kp.match_code,ktl.net_amount,ktl.gross_amount,ktl.db_portfolio_type,ktl.cr_portfolio_type from k$transaction_lines ktl
left join k$transaction_header kth on ktl.id=kth.id
left join k$portfolio kp on kp.id = (CASE WHEN ktl.db_portfolio_type = 'C' THEN ktl.db_portfolio ELSE ktl.cr_portfolio END)
where to_char(kth.trans_dte,'DD-MON-YY') >= '22-AUG-16'
and to_char(kth.trans_dte,'DD-MON-YY') <= '27-AUG-16'
and ktl.db_portfolio_type <> 'I'
and ktl.cr_portfolio is not null
order by kth.trans_dte, ktl.id, kp.match_code, kth.trtype
This is my query. I just want to know if I have something wrong with my where clause kth.trans_dte.
I only want to get Transactions from August 22 to Aug 27 but it I am getting transactions before that date, february and march are included when they shouldn't be. I wonder why.. Is there a problem with my code or is it something with the db that I don't know. Thanks!
you convert your field to char with to_char and then try to compare it datewise. to_char does exactly what it says - converts to a char string so you'll get dates according to ascii representation of the string
try using to_date instead - on both sides of the condition (s)
try using BETWEEN instead of 2 conditions .
select ktl.id, kth.trans_dte, kth.trtype, kp.match_code,ktl.net_amount,ktl.gross_amount,ktl.db_portfolio_type,ktl.cr_portfolio_type from k$transaction_lines ktl
left join k$transaction_header kth on ktl.id=kth.id
left join k$portfolio kp on kp.id = (CASE WHEN ktl.db_portfolio_type = 'C' THEN ktl.db_portfolio ELSE ktl.cr_portfolio END)
where (to_char(kth.trans_dte,'DD-MON-YY') >= '22-AUG-16'
and to_char(kth.trans_dte,'DD-MON-YY') <= '27-AUG-16')
and ktl.db_portfolio_type <> 'I'
and ktl.cr_portfolio is not null
order by kth.trans_dte, ktl.id, kp.match_code, kth.trtype
Try this.
try using between Keyword and to_date function in Query like
where kth.trans_dte between to_date('22-AUG-16')
and to_date('27-AUG-16')
and ktl.db_portfolio_type <> 'I'
and ktl.cr_portfolio is not null
order by kth.trans_dte, ktl.id, kp.match_code, kth.trtype
Sorry, I solved it just now. I can't use to_char when doing that condition that is why it gives the wrong results.

using count in a subquery and getting errors

i have line by line data in a table and i need to net of cancellations from sales and produce a report grouping on a scheme identifier. i.e i need to find all the sales and subtract all the cancellatsion to prduce a net sales figure.
i am trying to use the query below but i'm getting errors.
select insscheme, ((select count(quote_id) where (sale = '1')) - (select count(quote_id) where cancellation = '1')) as sales from policys
group by insscheme
order by insscheme
and i'm getting the error
Column 'policys.Sale' is invalid in the select list because it is not contained in either an aggregate function or the GROUP BY clause.
Can anyone help me out with this?
You don't need any sub queries here. Just use COUNT and CASE.
SELECT insscheme,
COUNT(CASE WHEN sale = '1' AND cancellation <> '1' THEN 1 END) AS sales
FROM policys
GROUP BY insscheme
ORDER BY insscheme
I have assumed above that cancellation is not nullable. If it is use
COUNT(CASE WHEN sale = '1' THEN 1 END) -
COUNT(CASE WHEN cancellation = '1' THEN 1 END) AS sales
Perhaps this might work.
select insscheme, SUM(sale) - SUM(cancellation) as NetSales
from policys
group by insscheme
I don't see what the quote_id column has to do with your query. Are you querying one table or several? It would help if you could show us what your schema looks like with a brief discussion of your table layout.