SQL Server: Apply different multipliers by date - sql-server

I have a table that records sales and I want a report on how much tax was paid on each item. The basic rule is all sales before April 1st had a .52% tax, all sales after that date will have a 0.5% tax.
I'm trying to get this using the following query
select ItemCode,
sum(Quantity) QuantitySold,
WhsCode as Store,
case when (docdate < '20170401') then sum(Quantity * .0052) else sum(Quantity * .005) end as Tax
from SalesTable
group by whscode,
itemcode
However I get a
DocDate' is invalid in the select list because it is not contained in
either an aggregate function or the GROUP BY clause.
error if I run it as is. Adding DocDate to the group by clause creates a mess of duplicates (On one example I went from 185 rows to 1508 rows).
Does SQL simply not allow you to use WHEN statements whose conditional is not included in the Group clause or should I be using something else?

Error is because you are using docdate directly without adding it to the group by clause.
I think this is what you want:
select ItemCode,
sum(Quantity) QuantitySold,
WhsCode as Store,
sum(price * case when docdate < '20170401' then 0.0052 else 0.005 end) as Tax
from SalesTable
group by whscode,
itemcode

Related

Make a summary report in SQL Server

I'm working on this database that I want it to create a summary sum(Amount) report on the all the tables that will be specified. I tried this but it didn't get what I expected.
SELECT SUM(Amount) AS Expenditure
FROM Expenditure
WHERE Amount IS NOT NULL
UNION ALL
SELECT SUM(Amount)
FROM auxiliary
WHERE Category IS NOT NULL AND Amount >0;
This only shows
and this is want to achieve:
How do I make that possible?
SELECT 'Expenditure' AS TableName, SUM(Amount) AS Amount
FROM Expenditure
WHERE Amount IS NOT NULL
UNION ALL
SELECT 'Auxiliary' AS TableName, SUM(Amount) AS Amount
FROM auxiliary
WHERE Category IS NOT NULL AND Amount >0;

How to display monetary value in PostgreSQL

My database query is below, but I still can't display a monetary value properly. Please help me.
SELECT SUM (orders.quantity * products.price) as total,
to_char((orders.quantity * products.price), '$99,999,999.99') AS money
FROM
orders
inner join products on products.id = orders.products_id
inner join customers on customers.id = orders.customers_id
WHERE order_date BETWEEN CURRENT_DATE - INTERVAL '30 days'
AND CURRENT_DATE + INTERVAL '1 days';
My problem is that I get this error:
ERROR: column "orders.quantity" must appear in the GROUP BY clause or be used in an aggregate function
You didn't really say what your problem was, but if you use the FM format modifier as in
SELECT to_char(12345.67, '$99,999,999.99FM');
to_char
------------
$12,345.67
(1 row)
the result might be more to your liking.
To make the query work without an error, add a GROUP BY clause at the end like
... GROUP BY money

SQL Sum and Group on two tables

I'm incredibly new to SQL and working on completing some assignments in order to advance my knowledge. I found myself stuck on a problem, though.
I have to find the total profit on items by using multiplication and subtraction, which I have completed with the following commands:
select
production.product.ProductID,
StandardCost,
sales.SalesOrderDetail.OrderQty,
UnitPrice,
(sales.SalesOrderDetail.UnitPrice*sales.SalesOrderDetail.OrderQty)-
(production.product.StandardCost*sales.salesorderdetail.OrderQty) as
'Total Profit'
from
sales.SalesOrderDetail,
production.product
What I need to do is sum the total profit and group it by the ProductID in order to find the most profitable items and the least profitable. I thought this would work:
select
production.product.ProductID,
StandardCost,
sales.SalesOrderDetail.OrderQty,
UnitPrice,
sum((sales.SalesOrderDetail.UnitPrice*sales.SalesOrderDetail.OrderQty)-
(production.product.StandardCost*sales.salesorderdetail.OrderQty)) as
'Total Profit'
from
sales.SalesOrderDetail,
production.product
group by
Production.Product.ProductID
However, I receive the following error:
Column 'production.product.StandardCost' is invalid in the select list because it is not contained in either an aggregate function or the GROUP BY clause.
I'm at a loss on where to continue. I tried rearranging and doing inner/left joins, but I've been unsuccessful.
so for grouping you need to aggregate or include in the group by statement.
you are grouping by the productID but the other columns are not aggregated and are not in the group by statement.
a correction could be (depending on how you want to aggregate the other columns)
select
production.product.ProductID
, avg(StandardCost) as AvgCost
, sum(sales.SalesOrderDetail.OrderQty) as TotalQuantity
, avg(UnitPrice) as AvgUnitPrice
, sum((sales.SalesOrderDetail.UnitPrice*sales.SalesOrderDetail.OrderQty)-
(production.product.StandardCost*sales.salesorderdetail.OrderQty)) as [Total Profit]
from sales.SalesOrderDetail
, production.product
group by Production.Product.ProductID

How can I aggregate data based on sub query results

I have a sql query like this:
SELECT (SUM(DURATIONSECS) / 3600.00) AS LaborHrs,
(SELECT LABORLEV2 t2 FROM LABOR WHERE LABORID = t1.LABORID) As Dept
FROM Table1 t1
WHERE DTM BETWEEN 'datetime1' AND 'datetime2' AND
(SELECT LABORLEV1 FROM LABOR WHERE LABORID = t1.LABORID) = '100'
AND PAYCODEID='1'
Group BY LABORID
This gives me the correct data like this:
LaborHrs Dept
90.5000000 office
1033.2500000 retail
522.2500000 retail
217.5000000 misc
1145.5000000 misc
40.0000000 retail
However I need the results to be aggregated if the dept name is the same for instance I need the sum of all labor hours of "retail" and "misc" to be in the same column. I have tried grouping by Dept, but it did not recognize that column name.
I rewrote your query based on what I understand of your question, but I'm pretty suspicious of this part:
DTM BETWEEN 'datetime1' AND 'datetime2'
I assume that it is a datetime variable or number that you would substitute in.
If that is the case, I guess here might be the answer.
SELECT (SUM(DURATIONSECS) / 3600.00) AS LaborHrs,
, l1.LABORLEV2 AS Dept
FROM Table1 t1
JOIN LABOR l1 ON l1 ON l1.LABORID=t1.LABORID
WHERE DTM BETWEEN 'datetime1' AND 'datetime2' AND l1.LABORLEV1='100'
AND t1.PAYCODEID='1'
Group BY t1.LABORID, l1.LABORLEV2
If you want to Group some column, the column can't be a subselect, so you will have to rewrite the query using JOINS.
By what I understant of your query, you can join the tables Tabl1 and LABOR and move your conditions to a single WHERE statement, something like this:
SELECT
l.LABORLEV2 AS Dept,
(SUM(t1.DURATIONSECS) / 3600.00) AS LaborHrs
FROM Table1 t
INNER JOIN LABOR l ON t.LABORID=l.LABORID
WHERE
l.LABORLEV1='100' AND
t1.PAYCODEID='1' AND
t1.DTM BETWEEN 'datetime1' AND 'datetime2'
GROUP BY l.LABORLEV2

SQl query to sum-up amounts by month/year

I have a table "TABLE" like this:
Date(datatime)
Paid(int)
I have multiple "Paid" amounts per month.
I would like to sum up the Paid amount per month/year.
So far this is what I tried but I get errors in EXTRACT and in MONTH and however I am far to get it done with the years.
SELECT
EXTRACT(MONTH FROM Period) AS reference_month
, SUM(Paid) AS monthly_payments
FROM Paid
GROUP BY EXTRACT(MONTH FROM Period)
ORDER BY EXTRACT(MONTH FROM Period)
I am not really handy at this and I would really appreciate some help.
select year(date) as y, month(date) as m, sum(paid) as p
from table
group by year(date), month(date)
SELECT YEAR([Date]) AS [Year], MONTH([Date]) AS [Month], SUM(Paid) AS Total
FROM TABLE_NAME
GROUP BY YEAR([Date]), MONTH([Date])
You need to use square brackets around your objects name [] when you have named your object with sql server key words.

Resources