SQL Server 2005. I need help building AR aging report . What is wrong with the script? - sql-server-2005

SELECT
invno,invdte,
CASE
WHEN (invdte >= (getdate() - 30) and itotal !=0 THEN 'itotal') AS '0-30'
WHEN (invdte BETWEEN getdate(), - 31) AND (getdate(), - 60) AND itotal !=0 THEN 'itotal') AS '31-60'
WHEN (invdte < getdate(),- 61) and itotal !=0 THEN 'itotal') AS '61>'
Else '0'
END AS [Aging AR]
SUM(itotal) AS 'Outstanding Total'
FROM
[01].[ARINVOI]
GROUP BY
invno, invdte
ORDER BY
Outstanding Total DESC

SELECT
invno, invdte,
SUM(CASE WHEN invdte >= (getdate() - 30) and itotal !=0 THEN itotal END) AS [0-30]
SUM(CASE WHEN invdte BETWEEN (getdate() - 31) AND (getdate() - 60) AND itotal !=0 THEN itotal END) AS [31-60]
SUM(itotal) AS 'Outstanding Total'
FROM
[01].[ARINVOI]
GROUP BY
invno, invdte
ORDER BY
Outstanding Total DESC

Related

Use a date based on field value

I need to find a way to relate two sets of orders. Essentially, and inbound versus outbound analysis for a report. A load balance to see when I need to organize more pickups or deliveries.
I need to pull the delivery_date when billing_group = 3
I need to pull the origin_date when billing_group = 4
Hope this made some sense. Thank you all!
select convert(varchar,Delivery_Date,101) as 'Delivery_Date',
convert(varchar,Origin_Date,101) as 'Origin_Date',
sum(case when billing_group = '3' then 1 else 0 end) as 'OR to WA',
sum(case when billing_group = '4' then 1 else 0 end) as 'WA to OR',
count(*) as Total_Orders
from orders
where Date >= dateadd(day, datediff(day, 0, GetDate()) - 30, 0) and
billing_group in ('3','4')
group by Date
order by date desc
Would it be possible to combine these two separate queries into one to provide a the following columns? date, OR to WA, and WA to OR (like in the example above) where the date (regardless of origin or delivery date is used
select convert(varchar,Delivery_Date,101) as 'Date',
sum(case when billing_group = '3' and delivery_date >= dateadd(day,datediff(day, 0, GetDate()) - 30, 0) then 1 else 0 end) as 'OR to WA'
from orders
where delivery_Date >= dateadd(day, datediff(day, 0, GetDate()) - 20, 0) and billing_group in ('3')
group by delivery_date
order by date desc
select convert(varchar,Origin_Date,101) as 'Date',
sum(case when billing_group = '4' and origin_date >= dateadd(day, datediff(day, 0, GetDate()) - 30, 0)then 1 else 0 end) as 'WA to OR'
from orders
where origin_Date >= dateadd(day, datediff(day, 0, GetDate()) - 20, 0) and billing_group in ('4')
group by origin_Date
order by date desc
I think you need to group by convert(varchar,Delivery_Date,101) instead of date.
When you use aggregate function you need to add non-aggregate colunms in group by.
select convert(varchar,Delivery_Date,101) as 'Delivery_Date',
sum(case when billing_group = '3' then 1 else 0 end) as 'OR to WA',
sum(case when billing_group = '4' then 1 else 0 end) as 'WA to OR',
count(*) as Total_Orders
from orders
where Date >= dateadd(day, datediff(day, 0, GetDate()) - 30, 0) and
billing_group in ('3','4')
group by convert(varchar,Delivery_Date,101)
order by date desc
EDIT
I saw you edit your question, you can try to use UNION ALL
SELECT * FROM (
select convert(varchar,Delivery_Date,101) as 'Date',
sum(case when billing_group = '3' and delivery_date >= dateadd(day,datediff(day, 0, GetDate()) - 30, 0) then 1 else 0 end) as 'OR to WA'
from orders
where delivery_Date >= dateadd(day, datediff(day, 0, GetDate()) - 20, 0) and billing_group in ('3')
group by delivery_date
UNION ALL
select convert(varchar,Origin_Date,101) as 'Date',
sum(case when billing_group = '4' and origin_date >= dateadd(day, datediff(day, 0, GetDate()) - 30, 0)then 1 else 0 end) as 'WA to OR'
from orders
where origin_Date >= dateadd(day, datediff(day, 0, GetDate()) - 20, 0) and billing_group in ('4')
group by origin_Date
) t1
ORDER BY Date desc

SQL - Average on DateDiff with taking out weekends

I have an SQL statement that calculates how many days late our vendors pay for invoices. It only includes weekdays and it works perfectly. My customer is now asking if I can have an average of those days late per vendor. Here is my code that works:
DATEDIFF(dd, PURCHTABLE.CONFIRMEDDLV, MAX(VENDPACKINGSLIPJOUR.DELIVERYDATE))
-(DATEDIFF(wk, PURCHTABLE.CONFIRMEDDLV, MAX(VENDPACKINGSLIPJOUR.DELIVERYDATE)) * 2)
-(CASE WHEN DATENAME(dw, PURCHTABLE.CONFIRMEDDLV) = 'Sunday'
THEN 1
ELSE 0
END)
-(CASE WHEN DATENAME(dw, MAX(VENDPACKINGSLIPJOUR.DELIVERYDATE)) = 'Saturday'
THEN 1
ELSE 0
END) AS 'DAYS LATE'
If I try to put this in an AVG(), but it tells me I cannot perform an aggregate function on an aggregate function.
UPDATE:
This is my original SQL:
SELECT
PURCHTABLE.PURCHNAME AS 'VENDOR NAME',
PURCHTABLE.ORDERACCOUNT AS 'VENDOR NUMBER',
COUNT(DISTINCT PURCHTABLE.PURCHID) AS 'PURCHASE ORDER',
COUNT(PURCHLINE.LINENUMBER) AS 'NUMBER OF LINES',
SUM(PURCHLINE.LINEAMOUNT) AS 'PO PRICE TOTAL',
DATEDIFF(dd, PURCHTABLE.CONFIRMEDDLV, MAX(VENDPACKINGSLIPJOUR.DELIVERYDATE))-(DATEDIFF(wk, PURCHTABLE.CONFIRMEDDLV, MAX(VENDPACKINGSLIPJOUR.DELIVERYDATE)) * 2)-(CASE WHEN DATENAME(dw, PURCHTABLE.CONFIRMEDDLV) = 'Sunday' THEN 1 ELSE 0 END)-(CASE WHEN DATENAME(dw, MAX(VENDPACKINGSLIPJOUR.DELIVERYDATE)) = 'Saturday' THEN 1 ELSE 0 END) AS 'DAYS LATE'
FROM
PURCHTABLE
JOIN
PURCHLINE ON PURCHLINE.PURCHID = PURCHTABLE.PURCHID
JOIN
VENDPACKINGSLIPJOUR ON VENDPACKINGSLIPJOUR.PURCHID = PURCHTABLE.PURCHID
WHERE
PURCHTABLE.DELIVERYDATE >= '2017-01-01'
AND
PURCHTABLE.DELIVERYDATE <= '2017-01-20'
AND
PURCHTABLE.ORDERACCOUNT = 'VN03526'
GROUP BY
PURCHTABLE.PURCHNAME,
PURCHTABLE.ORDERACCOUNT,
PURCHTABLE.DELIVERYDATE,
PURCHTABLE.CONFIRMEDDLV
So I don't quite understand how I change that to what you are saying.....I'm tried this but it's not working.
SELECT
PURCHTABLE.PURCHNAME AS 'VENDOR NAME',
PURCHTABLE.ORDERACCOUNT AS 'VENDOR NUMBER'
FROM
(SELECT
PURCHTABLE.PURCHNAME AS 'VENDOR NAME',
PURCHTABLE.ORDERACCOUNT AS 'VENDOR NUMBER',
COUNT(DISTINCT PURCHTABLE.PURCHID) AS 'PURCHASE ORDER',
COUNT(PURCHLINE.LINENUMBER) AS 'NUMBER OF LINES',
SUM(PURCHLINE.LINEAMOUNT) AS 'PO PRICE TOTAL',
DATEDIFF(dd, PURCHTABLE.CONFIRMEDDLV, MAX(VENDPACKINGSLIPJOUR.DELIVERYDATE))-(DATEDIFF(wk, PURCHTABLE.CONFIRMEDDLV, MAX(VENDPACKINGSLIPJOUR.DELIVERYDATE)) * 2)-(CASE WHEN DATENAME(dw, PURCHTABLE.CONFIRMEDDLV) = 'Sunday' THEN 1 ELSE 0 END)-(CASE WHEN DATENAME(dw, MAX(VENDPACKINGSLIPJOUR.DELIVERYDATE)) = 'Saturday' THEN 1 ELSE 0 END) AS 'DAYS LATE'
FROM
PURCHTABLE
JOIN
PURCHLINE ON PURCHLINE.PURCHID = PURCHTABLE.PURCHID
JOIN
VENDPACKINGSLIPJOUR ON VENDPACKINGSLIPJOUR.PURCHID = PURCHTABLE.PURCHID
WHERE
PURCHTABLE.DELIVERYDATE >= '2017-01-01'
AND
PURCHTABLE.DELIVERYDATE <= '2017-01-20'
AND
PURCHTABLE.ORDERACCOUNT = 'VN03526') A
GROUP BY
PURCHTABLE.PURCHNAME,
PURCHTABLE.ORDERACCOUNT,
PURCHTABLE.DELIVERYDATE,
PURCHTABLE.CONFIRMEDDLV
The code you have at the moment will be part of a larger query, such as:
select VendorID
,VendorName
...
...
,<Your Days Late Code> as DaysLate
,InvoiceAmount
...
from tables
group by VendorID
,VendorName
all you need to do to average over all of this is pick the other columns you want to do the average by and wrap the whole thing in another select statement:
select VendorID
,VendorName
,avg(DaysLate) as AverageDaysLate
,sum(InvoiceAmount) as TotalInvoiceAmount
from(
select VendorID
,VendorName
...
...
,<Your Days Late Code> as DaysLate
,InvoiceAmount
...
from tables
group by VendorID
,VendorName
) a
group by VendorID
,VendorName

Invalid in the select list because it is not contained in either an aggregate function or the group by clause case when

I can not put the column JobDeliveryDateIn in GROUP BY clause, SQL Server 2012, solution for this problem please.
SELECT TOP (100) PERCENT
StockCode,
CASE
WHEN JobDeliveryDate < GETDATE()
THEN SUM(QtyToMake - QtyManufactured)
ELSE SUM(0)
END AS Vencido,
CASE
WHEN JobDeliveryDate >= GETDATE() AND JobDeliveryDate < (GETDATE() + 5)
THEN SUM(QtyToMake - QtyManufactured)
ELSE SUM(0)
END AS Semana1,
CASE
WHEN JobDeliveryDate >= (GETDATE() + 5) AND JobDeliveryDate < (GETDATE() + 15)
THEN SUM(QtyToMake - QtyManufactured)
ELSE SUM(0)
END AS Semana2,
CASE
WHEN JobDeliveryDate >= (GETDATE() + 15)
THEN SUM(QtyToMake - QtyManufactured)
ELSE SUM(0)
END AS Futuro
FROM
SysproManutesa.dbo.WipMaster
WHERE
(Complete = 'N') AND (QtyManufactured < QtyToMake)
GROUP BY
StockCode
ORDER BY
StockCode
As per error message said, you can only use those column whose are in the group by and Aggregate Functions in the select list. (Check Aggregate Functions Here). As Case When is not aggregate function, SQL SERVER give you the error message. You need to change your query like below:
SELECT TOP (100) PERCENT
StockCode,
SUM(CASE WHEN JobDeliveryDate < GETDATE()
THEN (QtyToMake - QtyManufactured)
ELSE 0 END) AS Vencido,
SUM(CASE WHEN JobDeliveryDate >= GETDATE() AND JobDeliveryDate < (GETDATE() + 5)
THEN QtyToMake - QtyManufactured
ELSE 0 END) AS Semana1,
SUM(CASE WHEN JobDeliveryDate >= (GETDATE() + 5) AND JobDeliveryDate < (GETDATE() + 15)
THEN QtyToMake - QtyManufactured
ELSE 0 END) AS Semana2,
SUM(CASE WHEN JobDeliveryDate >= (GETDATE() + 15)
THEN QtyToMake - QtyManufactured
ELSE 0 END) AS Futuro
FROM SysproManutesa.dbo.WipMaster
WHERE (Complete = 'N') AND (QtyManufactured < QtyToMake)
GROUP BY StockCode
ORDER BY StockCode
You can't have the sums in the case statement but you can have the case statements in the sum... refactor statements like this:
CASE WHEN JobDeliveryDate < GETDATE() THEN SUM(QtyToMake - QtyManufactured) ELSE SUM(0) END AS Vencido,
to this
SUM(CASE WHEN JobDeliveryDate < GETDATE() THEN QtyToMake - QtyManufactured ELSE 0 END) AS Vencido,
Once you have done it a few times it will be clear why this works.
Just come across this problem and the way I have done it is to wrap the inner in a common table expression. I don't want to post my exact code but is goes something like this:
With CTE as (select case when [Type] like '%A%' or [Type] like '%b%' then null else ExpDate end as ExpDate, Amount from table)
select Expdate, sum(amount) from CTE group by Expdate
Gets around having views referencing other views which was my problem. Probably fine for most things, just beware of performance on big tables and data sets as I am not sure how CTEs use memory / disk / tempdb.

Group by within Sub Query

Hi I have the code below which brings through a total by due and complete as well as the date. However I want to summarize by date, please can someone assist?
SELECT CONVERT(varchar(15), GRLastDt, 111) as Date_,
(
SELECT COUNT(*) AS Expr1
FROM dbo.AN_Admin_VendorReturns_090_Final
WHERE (Complete = 'X') AND (CONVERT(varchar(15), GRLastDt, 111) >= GETDATE() - 60)
) AS Complete,
(
SELECT COUNT(*) AS Expr1
FROM dbo.AN_Admin_VendorReturns_090_Final AS AN_Admin_VendorReturns_090_Final_1
WHERE (Complete <> 'X') AND (CONVERT(varchar(15), GRLastDt, 111) >= GETDATE() - 60)
) AS DUE
FROM dbo.AN_Admin_VendorReturns_090_Final
group by CONVERT(varchar(15), GRLastDt, 111)
SELECT CGRLastDt as Date_,
SUM(CASE WHEN Complete = 'X' Then 1 Else 0 END) AS Complete,
SUM(CASE WHEN Complete <> 'X' Then 1 Else 0 END) AS Due
FROM dbo.AN_Admin_VendorReturns_090_Final
WHERE GRLastDt >= GETDATE() - 60
GROUP BY GRLastDt
Please note that I haven't validated this SQL for syntax and doing this in notepad.

Using CASE clause to find age

SELECT * FROM hr.Employees;
SELECT firstname,
lastname,
(CASE WHEN (month(getdate()) > month(birthdate))
THEN datediff(yy,birthdate,getdate())
ELSE datediff(yy,birthdate,getdate()) -1
END) AS _years, --years
(CASE WHEN (month(getdate()) > month(birthdate))
THEN month(getdate()) - month(birthdate)
ELSE month(getdate()) - month(birthdate) +12
END) AS _months, --months
(CASE WHEN (day(getdate()) > (day(birthdate)))
THEN day(getdate()) - day(birthdate)
ELSE month(getdate()) - month(birthdate) +11 & day(getdate()) + (day(EOMonth(birthdate)) - day(birthdate))
END) AS _days --days
FROM hr.Employees
Here is the code for finding age in yy,mm,dd. The problem I am having is in the days section.
I want to do is (if current day < birthdate day ) then (currentMonth-birthmonht)+11 and day(getdate()) + (day(EOMonth(birthdate)) - day(birthdate)).
I want to do is (if current day < birthdate day ) then
(currentMonth-birthmonht)+11 and day(getdate()) +
(day(EOMonth(birthdate)) - day(birthdate)).
This can't be done in the CASE in the days column you need to add a new WHEN clause in the CASE for month column itself. Like the following code
SELECT firstname,
lastname,
(CASE WHEN (month(getdate()) > month(birthdate)) THEN datediff(yy,birthdate,getdate())
ELSE datediff(yy,birthdate,getdate()) -1
END) AS years,
(CASE WHEN (month(getdate()) > month(birthdate)) THEN month(getdate()) - month(birthdate)
WHEN (day(getdate()) > (day(birthdate))) THEN month(getdate()) - month(birthdate) +11
ELSE month(getdate()) - month(birthdate) +12
END) AS months,
(CASE WHEN (day(getdate()) > (day(birthdate))) THEN day(getdate()) - day(birthdate)
ELSE day(getdate()) + (day(EOMonth(birthdate)) - day(birthdate))
END) AS days
FROM Employees
Here is a SQL fiddle demo of the query: SQL Fiddle
If you can use T-SQL this answer shows how to do this in T-SQL.