Revenue for two months date wise - sql

I am trying to get data for last 2 month ...but the query does not give perfect result....
SELECT DAY(table_A.PaymentDate) as date1 ,
(case when MONTH(table_A.PaymentDate) = MONTH(CURRENT_TIMESTAMP) - 1
then CAST(SUM(table_A.Total_Amount) AS INT)
else 0
end) AS last_month_CNT,
(case when MONTH(table_A.PaymentDate) = MONTH(CURRENT_TIMESTAMP)
then CAST(SUM(table_A.Total_Amount) As INT)
else 0
end) as This_month_CNT
FROM Tbl_Pan_Paymentdetails table_A
FULL OUTER JOIN Tbl_Pan_Paymentdetails table_B
ON table_A.PaymentDate=table_B.PaymentDate
WHERE YEAR(table_A.PaymentDate) = YEAR(CURRENT_TIMESTAMP)
AND
table_A.PaymentDate >= DATEADD(MONTH, -1, GETDATE())
GROUP BY
DAY(table_A.PaymentDate) ,MONTH(table_A.PaymentDate)
order by
DAY(table_A.PaymentDate);

Move the entire case expression inside the sum function and don't include the month in the group by. Also, the full outer join seems unnecessary so I removed it.
This should be what you are looking for:
SELECT
DAY(PaymentDate) as date1 ,
SUM(CASE WHEN MONTH(PaymentDate) = MONTH(CURRENT_TIMESTAMP)-1 THEN CAST(Total_Amount AS INT) ELSE 0 END) AS last_month_CNT,
SUM(CASE WHEN MONTH(PaymentDate) = MONTH(CURRENT_TIMESTAMP) THEN CAST(Total_Amount AS INT) ELSE 0 END) AS This_month_CNT
FROM Tbl_Pan_Paymentdetails
WHERE YEAR(PaymentDate) = YEAR(CURRENT_TIMESTAMP)
AND PaymentDate >= DATEADD(MONTH, -1, GETDATE())
GROUP BY DAY(PaymentDate)
ORDER BY DAY(PaymentDate);

Related

How can I include more columns other than just percentage column in my sql query result?

When I use the below query I only get percentage column but I want the (buyer_id, buyer_name, created_date,total_work_orders_with_gtv_first_60_days, total_gtv_first_60_days, total_net_amount_first_60_days) to show as columns too. Would really appreciate your help please.
WITH results_cte AS (
SELECT
b.buyer_id,
b.buyer_name,
CAST(b.created_date AS DATE) AS created_date,
COALESCE(wo.total_work_orders_with_gtv_first_60_days, 0) AS total_work_orders_with_gtv_first_60_days,
COALESCE(wo.total_gtv_first_60_days, 0) AS total_gtv_first_60_days,
COALESCE(wo.total_net_amount_first_60_days, 0) AS total_net_amount_first_60_days
FROM dw.buyer b
LEFT JOIN (SELECT wo.buyer_id,
COUNT(CASE WHEN wo.gtv_date < DATEADD(DAY, 60, b.created_date) THEN wo.work_order_id ELSE NULL END) AS total_work_orders_with_gtv_first_60_days,
SUM(CASE WHEN wo.gtv_date < DATEADD(DAY, 60, b.created_date) THEN wo.gtv ELSE NULL END) AS total_gtv_first_60_days,
SUM(CASE WHEN wo.gtv_date < DATEADD(DAY, 60, b.created_date) THEN wo.net_amount ELSE NULL END) AS total_net_amount_first_60_days
FROM dw.work_order wo
JOIN dw.buyer b
ON wo.buyer_id = b.buyer_id
WHERE wo.gtv > 0
GROUP BY wo.buyer_id) wo
ON b.buyer_id = wo.buyer_id
WHERE b.buyer_segmentation = 'S - Self-Service'
AND b.status = 'Active'
AND b.created_date >= DATEADD(YEAR, -1, GETDATE())
)
SELECT (SELECT CAST(count(DISTINCT buyer_id) AS float) FROM results_cte WHERE total_work_orders_with_gtv_first_60_days > 0)
/ (SELECT CAST(count(DISTINCT buyer_id) AS float) FROM results_cte ) AS percentage

SQL code to set a specific date as compared to "today's" date

In the first column (Report_Date) of this query the date is being constructed and is today's day, and is used in the following lines to select is the following columns. I'd like to use a specific day in the query.
I'd like help to write the format to replace column 1 (Report_Date) with a different date to create aging, like June 1st - 2021-06-01.
SELECT
convert(datetime,convert(char,datepart(mm,getdate()))+'/'+convert(char,datepart(dd,getdate()))+'/'+convert(char,datepart(yyyy,getdate())))Report_Date,
sum(case
when datediff(dd, (convert(datetime,convert(char,B.Original_Bill_Date,101))), getdate())
Between 0 and 30 then B.CurrentBalance else 0
end) '0-30',
sum(case
when datediff(dd, (convert(datetime,convert(char,B.Original_Bill_Date,101))), getdate())
Between 31 and 60 then B.CurrentBalance else 0
end) '31-60',
sum(case
when datediff(dd, (convert(datetime,convert(char,B.Original_Bill_Date,101))), getdate())
Between 61 and 90 then B.CurrentBalance else 0
end) '61-90',
sum(case
when datediff(dd, (convert(datetime,convert(char,B.Original_Bill_Date,101))), getdate())
Between 91 and 120 then B.CurrentBalance else 0
end) '91-120',
B.Primary_Payer_Code,
B.Secondary_Payer_Code,
B.CurrentResponsibility_desc,
Case When G.PAYER_GROUP IS NOT NULL Then G.PAYER_GROUP
Else Case When B.Primary_Payer_Code = 'PP' Then 'SELF PAY' Else
F.Description End End
FROM
Date D with (nolock)
JOIN TEL_BILLED_LINE_ITEM_ODS B with (nolock) ON ( convert(datetime,convert(char,B.Original_Bill_Date,101)) = D.DATE)
LEFT OUTER JOIN TBLPAYER_ODS P with (nolock) ON B.Primary_Payer_Code=P.Code
LEFT OUTER JOIN TBLFINANCIALCLASS_ODS F with (nolock) ON F.tblfinancialclassid = P.FinancialClassID
LEFT OUTER JOIN PAYER_GROUP G ON G.PAYER_CODE = P.CODE
WHERE
( B.CurrentBalance != 0)
AND B.BadDebtFlagYN=0
AND B.Primary_Payer_Code !='CL' -- exclude CLIENT 07/01/2010 jdw
GROUP BY
B.Primary_Payer_Code,
B.Secondary_Payer_Code,
B.CurrentResponsibility_desc,
Case When G.PAYER_GROUP IS NOT NULL Then G.PAYER_GROUP
Else Case When B.Primary_Payer_Code = 'PP' Then 'SELF PAY' Else
F.Description End End

SQL Server issue with select and group by with calculated columns

I have this SQL I am trying to build:
select
a.Name,
(SELECT COUNT(b.PlannedCollectionDate) WHERE b.PlannedCollectionDate < GETDATE()) AS Due,
(SELECT COUNT(b.PlannedCollectionDate) WHERE b.PlannedCollectionDate = GETDATE()) AS Today,
(SELECT COUNT(b.PlannedCollectionDate) WHERE b.PlannedCollectionDate = DATEADD(DAY, 1, GETDATE())) AS Expected,
(SELECT COUNT(b.PlannedCollectionDate) WHERE b.PlannedCollectionDate > DATEADD(DAY, 1, GETDATE())) AS Planned
from Centers AS a
INNER JOIN Collections AS b
ON a.Id = b.CenterId
GROUP BY a.Name
But I get an error:
Column 'Collections.PlannedCollectionDate' is invalid in the select list because it is not contained in either an aggregate function or the GROUP BY clause.
I know I could do something like this:
select
a.Name,
(SELECT COUNT(Id) FROM Collections WHERE CenterId = a.Id AND PlannedCollectionDate < GETDATE()) AS Due,
(SELECT COUNT(Id) FROM Collections WHERE CenterId = a.Id AND PlannedCollectionDate = GETDATE()) AS Today,
(SELECT COUNT(Id) FROM Collections WHERE CenterId = a.Id AND PlannedCollectionDate = DATEADD(DAY, 1, GETDATE())) AS Expected,
(SELECT COUNT(Id) FROM Collections WHERE CenterId = a.Id AND PlannedCollectionDate > DATEADD(DAY, 1, GETDATE())) AS Planned
from Centers AS a
But I assume that is slower because I have to do multiple selects from the same table (Collections).
So, my question is, what can I do to make my first query work? I don't think grouping by PlannedCollectionDate is right, because it will mess up my count
I think you want conditional aggregation:
select ce.Name,
SUM(CASE WHEN co.PlannedCollectionDate < GETDATE() THEN 1 ELSE 0 END) AS Due,
SUM(CASE WHEN co.PlannedCollectionDate = GETDATE() THEN 1 ELSE 0 END) AS Today,
SUM(CASE WHEN co.PlannedCollectionDate = DATEADD(DAY, 1, GETDATE()) THEN 1 ELSE 0 END) AS Expected,
SUM(CASE WHEN co.PlannedCollectionDate > DATEADD(DAY, 1, GETDATE()) THEN 1 ELSE 0 END) AS Planned
from Centers ce join
Collections co
on ce.Id = co.CenterId
group by ce.Name;
This implements what you have written. Do note the use of meaningful table aliases.
However, it will not do what you want, because GETDATE() has a time component. To fix that, convert it to a date:
select ce.Name,
SUM(CASE WHEN co.PlannedCollectionDate < CONVERT(DATE, GETDATE()) THEN 1 ELSE 0 END) AS Due,
SUM(CASE WHEN co.PlannedCollectionDate = CONVERT(DATE, GETDATE()) THEN 1 ELSE 0 END) AS Today,
SUM(CASE WHEN co.PlannedCollectionDate = DATEADD(DAY, 1, CONVERT(DATE, GETDATE())) THEN 1 ELSE 0 END) AS Expected,
SUM(CASE WHEN co.PlannedCollectionDate > DATEADD(DAY, 1, CONVERT(DATE, GETDATE())) THEN 1 ELSE 0 END) AS Planned
from Centers ce join
Collections co
on ce.Id = co.CenterId
group by ce.Name;
Note that this assumes that PlannedCollectionDate does not have a time component.

How to Change SQL select query As new table in SQL Server CE?

This is my current SQL query:
SELECT
SUM(CASE WHEN (DATEDIFF(day, tbl_debit.purchasedate, GETDATE()) >= 45)
THEN tbl_invoices.pendingamount ELSE 0 END) AS morethan45,
SUM(CASE WHEN (DATEDIFF(day, tbl_debit.purchasedate, GETDATE()) < 45)
THEN tbl_invoices.pendingamount ELSE 0 END) AS lessthan45
FROM
tbl_debit
INNER JOIN
tbl_invoices ON tbl_debit.invoice = tbl_invoices.invoice
WHERE
(tbl_invoices.state = - 1)
Output of above query is shown here:
morethan45 | lessthan45
750 | 710
And I want to create a new table like below. Is it possible to create something new like below
Column 1 | Column 2
morethan45 | 750
lessthan45 | 710
Same query can be altered a bit to get the result.
Instead of aggregating the pendingamount based on condition you can add a new column to define the range and use it in Group by
SELECT CASE
WHEN Datediff(day, tbl_debit.purchasedate, Getdate()) >= 45 THEN 'morethan45'
ELSE 'lessthan45'
END AS [Column 1],
Sum(tbl_invoices.pendingamount) AS [Column 2]
FROM tbl_debit
INNER JOIN tbl_invoices
ON tbl_debit.invoice = tbl_invoices.invoice
WHERE tbl_invoices.state = -1
GROUP BY CASE
WHEN ( Datediff(day, tbl_debit.purchasedate, Getdate()) >= 45 ) THEN 'morethan45'
ELSE 'lessthan45'
END
Use the case in a group by:
SELECT (CASE WHEN (DATEDIFF(day, tbl_debit.purchasedate, GETDATE()) >= 45)
THEN 'MoreThan45'
ELSE 'LessThan45'
END) as Column1,
SUM(tbl_invoices.pendingamount) as Column2
FROM tbl_debit INNER JOIN
tbl_invoices
ON tbl_debit.invoice = tbl_invoices.invoice
WHERE tbl_invoices.state = -1
GROUP BY (CASE WHEN (DATEDIFF(day, tbl_debit.purchasedate, GETDATE()) >= 45)
THEN 'MoreThan45'
ELSE 'LessThan45'
END);
Use into or insert to populate a table.

SQL Query: Cannot perform aggregate functions on sub queries

I have the following SQL query
SELECT
[Date],
DATENAME(dw,[Date]) AS Day,
SUM(CASE WHEN ChargeCode IN (SELECT ChargeCode FROM tblChargeCodes WHERE Chargeable = 1) THEN Units ELSE 0 END) ChargeableTotal,
SUM(CASE WHEN ChargeCode IN (SELECT ChargeCode FROM tblChargeCodes WHERE Chargeable = 0) THEN Units ELSE 0 END) NotChargeableTotal,
SUM(Units) AS TotalUnits
FROM
tblTimesheetEntries
WHERE
UserID = 'PJW'
AND Date >= '2013-01-01'
GROUP BY
[Date]
ORDER BY
[Date] DESC;
But I get the error message:
Cannot perform an aggregate function on an expression containing an aggregate or a subquery.
Because I am using sub queries in the Case Else Summation.
How can I revise my query to get 2 x Sums of [Units] one for Chargeable = true, and one for Chargeable = false, even though the Chargeable field is in a different table to all the other information. The two tables are linked by ChargeCode which appears in both tblTimesheetEntries and tblChargeCodes.
Have you tried joining the tables on the chargeCode:
SELECT e.[Date],
DATENAME(dw,e.[Date]) AS Day,
SUM(CASE WHEN c.Chargeable = 1 THEN e.Units ELSE 0 END) ChargeableTotal,
SUM(CASE WHEN c.Chargeable = 0 THEN e.Units ELSE 0 END) NotChargeableTotal,
SUM(e.Units) AS TotalUnits
FROM tblTimesheetEntries e
LEFT JOIN tblChargeCodes c
on e.ChargeCode = c.ChargeCode
WHERE e.UserID = 'PJW'
AND e.Date >= '2013-01-01'
GROUP BY e.[Date]
ORDER BY e.[Date] DESC;