How to derive weekdays from query? - sql

How to I get the weekday name after OrderH_dtmInitiated column
SELECT
Convert(char(8), OrderH_dtmInitiated, 112) AS BookingDate,
--(To derived weekdays name from OrderH_dtmInitiated namely weekdays here)
[OrderH_strEmailConfirmationSent], [OrderH_strEmail]
FROM
[VISTAIT].[dbo].[tblOrderHistory]
WHERE
OrderH_strEmailConfirmationSent IS NULL
AND OrderH_dtmInitiated >= (SELECT DATEADD(dd, 0, DATEDIFF(dd, 0, GETDATE()-1)))
ORDER BY
Convert(char(8), OrderH_dtmInitiated, 112)

You could use datename:
SELECT
Convert(char(8), OrderH_dtmInitiated, 112) As BookingDate,
Datename (weekday, OrderH_dtmInitiated) As NameOfDay,
[OrderH_strEmailConfirmationSent]
,[OrderH_strEmail]
FROM [VISTAIT].[dbo].[tblOrderHistory]
WHERE OrderH_strEmailConfirmationSent is NULL And OrderH_dtmInitiated >= (SELECT DATEADD(dd, 0, DATEDIFF(dd, 0, GETDATE()-1)))
ORDER by Convert(char(8), OrderH_dtmInitiated, 112)

SELECT
Convert(char(8), OrderH_dtmInitiated, 112)as datebooking,
Datename (weekday, OrderH_dtmInitiated) As NameOfDay,
count(distinct OrderH_strCinemaId)as cinemassite,
count(distinct OrderH_intID)as TotalBookingMade,
SUM(case when OrderH_strEmailConfirmationSent like 'Y' then 1 else 0 end) as OrderH_strEmailConfirmationSent,
SUM(case when OrderH_strEmailConfirmationSent is NULL then 1 else 0 end) as EmailHavingNull
FROM [VISTAIT].[dbo].[tblOrderHistory]
WHERE OrderH_dtmInitiated >= '2015-05-07'
GROUP BY Convert(char(8), OrderH_dtmInitiated, 112)
ORDER by Convert(char(8), OrderH_dtmInitiated, 112)

Related

SQL - AVG Output is incorrect

In below query, I am calculating the lead time between two different dates and eventually trying to get the average of that lead time but the output is incorrect.
SELECT
Round(AVG(CAST(
Case when CONVERT(datetime, ORDERDATE, 105) = CONVERT(datetime, INVOUTDATE, 105) THEN 0 else
Case when CONVERT(datetime, ORDERDATE, 105) + 1 = CONVERT(datetime, INVOUTDATE, 105) THEN 1 else
(DATEDIFF(dd, CONVERT(datetime, ORDERDATE, 105), CONVERT(datetime, INVOUTDATE, 105)))
-(DATEDIFF(wk, CONVERT(datetime, ORDERDATE, 105), CONVERT(datetime, INVOUTDATE, 105))*1)
-(CASE WHEN DATENAME(dw, CONVERT(datetime, ORDERDATE, 105)) = 'Sunday' THEN 1 ELSE 0 END)
-(CASE WHEN DATENAME(dw, CONVERT(datetime, INVOUTDATE, 105)) = 'Sunday' THEN 0 ELSE 0 END) end end AS FLOAT)),4) AS LEADTIME FROM DSORDERSTATUS
WHERE ORDERTYPE <> 'Exchange Order'
AND CONVERT(datetime, ORDERDATE, 105) between '20170801' and '20170831'
AND CONVERT(datetime, INVOUTDATE, 105) IS NOT NULL
To troubleshoot the above query I extract the data by using the same query below and when I manually calculate the lead time and average it was correct.
Don't know where is the issue? can someone please tell me whether anything wrong with my query.
Please click on the link to refer sample data Link
SELECT DISTINCT DOCKETNO,
Case when CONVERT(datetime, ORDERDATE, 105) = CONVERT(datetime, INVOUTDATE, 105) THEN 0 else
Case when CONVERT(datetime, ORDERDATE, 105) + 1 = CONVERT(datetime, INVOUTDATE, 105) THEN 1 else
(DATEDIFF(dd, CONVERT(datetime, ORDERDATE, 105), CONVERT(datetime, INVOUTDATE, 105)))
-(DATEDIFF(wk, CONVERT(datetime, ORDERDATE, 105), CONVERT(datetime, INVOUTDATE, 105))*1)
-(CASE WHEN DATENAME(dw, CONVERT(datetime, ORDERDATE, 105)) = 'Sunday' THEN 1 ELSE 0 END)
-(CASE WHEN DATENAME(dw, CONVERT(datetime, INVOUTDATE, 105)) = 'Sunday' THEN 0 ELSE 0 END) end end AS LEADTIME FROM DSORDERSTATUS
WHERE ORDERTYPE <> 'Exchange Order'
AND CONVERT(datetime, ORDERDATE, 105) between '20170801' and '20170831'
AND CONVERT(datetime, INVOUTDATE, 105) IS NOT NULL
ok, now I understand..
I think you have to group by orders before to calculate avg
;with
S AS (
select DOCKETNO, ORDERDATE, INVOUTDATE, COUNT(*) n
from DSORDERSTATUS where ORDERTYPE <> 'Exchange Order'
group by DOCKETNO, ORDERDATE, INVOUTDATE
),
D as (
select [DOCKETNO], [ORDERDATE], [INVOUTDATE],
DATEDIFF(dd, CONVERT(date, [ORDERDATE], 105), CONVERT(date, [INVOUTDATE], 105)) dd,
DATEDIFF(wk, CONVERT(date, [ORDERDATE], 105), CONVERT(date, [INVOUTDATE], 105)) wk,
CASE WHEN DATEPART(dw, CONVERT(datetime, ORDERDATE, 105)) = 7 THEN 1 ELSE 0 END IsSundayOrd,
CASE WHEN DATEPART(dw, CONVERT(datetime, INVOUTDATE, 105)) = 7 THEN 1 ELSE 0 END IsSundayInv
from S
)
select avg(cast(dd - case when dd>1 then (wk + IsSundayOrd + IsSundayInv) else 0 end as float)) leadtime
from D
where CONVERT(date, ORDERDATE, 105) between '20170801' and '20170831'
AND CONVERT(date, INVOUTDATE, 105) IS NOT NULL
I will try to convert your dates to DATE instesad of DATETIME I think you are filtering too much rows because '20170831' is '2017-08-31 00:00:00' and you are loosing all ORDERDATE between '00:00:00' and '23:59:59' (for '2017-08-31')
WHERE ORDERTYPE <> 'Exchange Order'
AND CONVERT(date, ORDERDATE, 105) between '20170801' and '20170831'
AND CONVERT(date, INVOUTDATE, 105) IS NOT NULL
With the help of MtwStark i was able to resolve this.
I have modified his query,
Thanks buddy
;with
S AS (
SELECT DISTINCT DOCKETNO,
Case when CONVERT(datetime, ORDERDATE, 105) = CONVERT(datetime, INVOUTDATE, 105) THEN 0 else
Case when CONVERT(datetime, ORDERDATE, 105) + 1 = CONVERT(datetime, INVOUTDATE, 105) THEN 1 else
(DATEDIFF(dd, CONVERT(datetime, ORDERDATE, 105), CONVERT(datetime, INVOUTDATE, 105)))
-(DATEDIFF(wk, CONVERT(datetime, ORDERDATE, 105), CONVERT(datetime, INVOUTDATE, 105))*1)
-(CASE WHEN DATENAME(dw, CONVERT(datetime, ORDERDATE, 105)) = 'Sunday' THEN 1 ELSE 0 END)end end AS LEADTIME FROM DSORDERSTATUS
WHERE ORDERTYPE <> 'Exchange Order'
AND CONVERT(datetime, ORDERDATE, 105) between '20170801' and '20170808'
AND CONVERT(datetime, INVOUTDATE, 105) IS NOT NULL
),
D AS (
SELECT DOCKETNO, LEADTIME FROM S
)
SELECT AVG(CAST(LEADTIME AS FLOAT)) FROM D

Select top 50 rows in sql server

I have below T-SQL code used in SQL Server 2014.
This code produces 1000s of rows. But i need only top 50 rows (from Supplier Column) from this.
In the below code, if I use SELECT Top 50 s.[CusNo] Supplier then I am not getting desired results.
What changes needs to be done in the below code in order to get only Top 50 rows (of Supplier column) with out any change in the existing result.
SELECT s.[CusNo] Supplier,
RTRIM(CAST(s.[Customer] AS VARCHAR(50)) ) AS Name,
s.[ConcessionNo] Concession,
RTRIM(CAST(s.[ConcessionName] AS VARCHAR(50)) ) AS ConcessionName,
sum(case when s.Date between convert(date,dateadd(wk, datediff(wk, 0, getdate()) - 1, 0) - 1) and convert(date,dateadd(wk, datediff(wk, 0, getdate()) - 1, 0) + 5)
then s.SELLINC else 0 end) ActualSales,
sum(case when s.Date between convert(date,dateadd(wk, datediff(wk, 0, dateadd(YEAR, - 1, getdate())) - 1, 0) -1 /* On 14/Feb/2021 modify +6 to -1 */) and convert(date,dateadd(wk, datediff(wk, 0, dateadd(YEAR, - 1, getdate())) - 1, 0) + 5 /* On 14/Feb/2021 modify +12 to +5 */)
then s.SELLINC else 0 end) LastYrVariance,
(sum(case when s.Date between convert(date,dateadd(wk, datediff(wk, 0, getdate()) - 1, 0) - 1) and convert(date,dateadd(wk, datediff(wk, 0, getdate()) - 1, 0) + 5) then s.SELLINC else 0 end))-
(sum(case when s.Date between convert(date,dateadd(wk, datediff(wk, 0, dateadd(YEAR, - 1, getdate())) - 1, 0) -1 /* On 14/Feb/2021 modify +6 to -1 */) and convert(date,dateadd(wk, datediff(wk, 0, dateadd(YEAR, - 1, getdate())) - 1, 0) + 5 /* On 14/Feb/2021 modify +12 to +5 */) then s.SELLINC else 0 end)) LastYrVariancePounds,
(IsNull(sum(case when s.Date between convert(date,dateadd(wk, datediff(wk, 0, getdate()) - 1, 0) - 1) and convert(date,dateadd(wk, datediff(wk, 0, getdate()) - 1, 0) + 5)
then s.SELLINC else 0 end)-sum(case when s.Date between convert(date,dateadd(wk, datediff(wk, 0, dateadd(YEAR, - 1, getdate())) - 1, 0) -1 /* On 14/Feb/2021 modify +6 to -1 */) and convert(date,dateadd(wk, datediff(wk, 0, dateadd(YEAR, - 1, getdate())) - 1, 0) + 5 /* On 14/Feb/2021 modify +12 to +5 */)
then s.SELLINC else 0 end),0)/NullIf(sum(case when s.Date between convert(date,dateadd(wk, datediff(wk, 0, dateadd(YEAR, - 1, getdate())) - 1, 0) -1 /* On 14/Feb/2021 modify +6 to -1 */) and convert(date,dateadd(wk, datediff(wk, 0, dateadd(YEAR, - 1, getdate())) - 1, 0) + 5 /* On 14/Feb/2021 modify +12 to +5 */)
then s.SELLINC else 0 end),0))*100 LastYrVariancePercentage,
sum(case when s.Date
BETWEEN
convert(varchar(10), DATEADD(day, DATEDIFF(day, '19000107', DATEADD(month, DATEDIFF(MONTH, 0, CONVERT(date, CONVERT(VARCHAR(4), (CASE WHEN MONTH(GetDate()) = 1 THEN CONVERT(VARCHAR(4), GetDate(), 112) - 1 ELSE CONVERT(VARCHAR(4), GetDate(), 112) END), 112) + '0101')), 30)) / 7 * 7, '19000107'), 120)
AND
Convert(date, dateadd(wk, datediff(wk, 0, GETDATE()) - 1, 0) + 5)
then s.SELLINC else 0 end) YrToDateActual,
sum(case when s.Date
BETWEEN
convert(varchar(10), DATEADD(day, DATEDIFF(day, '19000107', DATEADD(month, DATEDIFF(MONTH, 0, CONVERT(date, CONVERT(VARCHAR(4), (CASE WHEN MONTH(DATEADD(year,-1,GetDate())) = 1 THEN CONVERT(VARCHAR(4), DATEADD(year,-1,GetDate()), 112) - 1 ELSE CONVERT(VARCHAR(4), DATEADD(year,-1,GetDate()), 112) END), 112) + '0101')), 30)) / 7 * 7, '19000107'), 120)
AND
convert(date,dateadd(wk, datediff(wk, 0, dateadd(YEAR, - 1, getdate())) - 1, 0) + 5 /* On 14/Feb/2021 modify +12 to +5 */)
then s.SELLINC else 0 end) LastYrToDateActual,
(sum(case when s.Date
BETWEEN
convert(varchar(10), DATEADD(day, DATEDIFF(day, '19000107', DATEADD(month, DATEDIFF(MONTH, 0, CONVERT(date, CONVERT(VARCHAR(4), (CASE WHEN MONTH(GetDate()) = 1 THEN CONVERT(VARCHAR(4), GetDate(), 112) - 1 ELSE CONVERT(VARCHAR(4), GetDate(), 112) END), 112) + '0101')), 30)) / 7 * 7, '19000107'), 120)
AND
Convert(date, dateadd(wk, datediff(wk, 0, GETDATE()) - 1, 0) + 5)
then s.SELLINC else 0 end))
-
(sum(case when s.Date
BETWEEN
convert(varchar(10), DATEADD(day, DATEDIFF(day, '19000107', DATEADD(month, DATEDIFF(MONTH, 0, CONVERT(date, CONVERT(VARCHAR(4), (CASE WHEN MONTH(DATEADD(year,-1,GetDate())) = 1 THEN CONVERT(VARCHAR(4), DATEADD(year,-1,GetDate()), 112) - 1 ELSE CONVERT(VARCHAR(4), DATEADD(year,-1,GetDate()), 112) END), 112) + '0101')), 30)) / 7 * 7, '19000107'), 120)
AND
convert(date,dateadd(wk, datediff(wk, 0, dateadd(YEAR, - 1, getdate())) - 1, 0) + 5 /* On 14/Feb/2021 modify +12 to +5 */)
then s.SELLINC else 0 end)) YrToDateVariancePounds,
((IsNull
(
(sum(case when s.Date
BETWEEN
convert(varchar(10), DATEADD(day, DATEDIFF(day, '19000107', DATEADD(month, DATEDIFF(MONTH, 0, CONVERT(date, CONVERT(VARCHAR(4), (CASE WHEN MONTH(GetDate()) = 1 THEN CONVERT(VARCHAR(4), GetDate(), 112) - 1 ELSE CONVERT(VARCHAR(4), GetDate(), 112) END), 112) + '0101')), 30)) / 7 * 7, '19000107'), 120)
AND
Convert(date, dateadd(wk, datediff(wk, 0, GETDATE()) - 1, 0) + 5)
then s.SELLINC else 0 end))
-
(sum(case when s.Date
BETWEEN
convert(varchar(10), DATEADD(day, DATEDIFF(day, '19000107', DATEADD(month, DATEDIFF(MONTH, 0, CONVERT(date, CONVERT(VARCHAR(4), (CASE WHEN MONTH(DATEADD(year,-1,GetDate())) = 1 THEN CONVERT(VARCHAR(4), DATEADD(year,-1,GetDate()), 112) - 1 ELSE CONVERT(VARCHAR(4), DATEADD(year,-1,GetDate()), 112) END), 112) + '0101')), 30)) / 7 * 7, '19000107'), 120)
AND
convert(date,dateadd(wk, datediff(wk, 0, dateadd(YEAR, - 1, getdate())) - 1, 0) + 5 /* On 14/Feb/2021 modify +12 to +5 */)
then s.SELLINC else 0 end))
,0)
)
/
(NullIf
(
sum(case when s.Date
BETWEEN
convert(varchar(10), DATEADD(day, DATEDIFF(day, '19000107', DATEADD(month, DATEDIFF(MONTH, 0, CONVERT(date, CONVERT(VARCHAR(4), (CASE WHEN MONTH(DATEADD(year,-1,GetDate())) = 1 THEN CONVERT(VARCHAR(4), DATEADD(year,-1,GetDate()), 112) - 1 ELSE CONVERT(VARCHAR(4), DATEADD(year,-1,GetDate()), 112) END), 112) + '0101')), 30)) / 7 * 7, '19000107'), 120)
AND
convert(date,dateadd(wk, datediff(wk, 0, dateadd(YEAR, - 1, getdate())) - 1, 0) + 5 /* On 14/Feb/2021 modify +12 to +5 */)
then s.SELLINC else 0 end)
,0)))*100 LastYrToDateVariancePercentage
FROM [dbo].[CustomerReports] s
WHERE s.BRN = 1 or s.BRN = 2 or s.BRN = 3 or s.BRN = 4 or s.BRN = 5 or s.SELLINC is null or s.SELLINC = '0'
GROUP BY s.[CusNo], s.[Customer], s.ConcessionNo, s.ConcessionName
order by YrToDateActual desc
When I run this Query In SSRS I get below results (Which is Correct). But displays all the data.
if I use SELECT Top 50 s.[CusNo] Supplier (Rest of the code is same) then I am getting the below,
So please see the highlighted section in both the images. When I add Top 50 in SQL code then few rows (in 3rd column ) which were present in 1st image is not present in 2nd image.
Try this:
With cte as (**your long query goes here**)
Select Top(50) * From cte
The sort order in your query is by YrToDateActual desc, so the TOP 50 is giving you the highest 50 YrToDateActual amounts. Your SSRS report is grouping by Supplier number and name, but doesn't look to be sorting by either of these columns, so I'm guessing that the order of these suppliers is somewhat random in the SSRS output. In this case I don't think you're ever going to be able to get the first 50 rows of your original SSRS output. The best you could do would be to also sort your SSRS output (e.g. by Supplier number) and then add this sort into your query (order by Supplier, YrToDateActual desc). Adding the TOP 50 into your query would cut off your new sorted SSRS output after the first 50 results.
What do you want to see in the report? Do you want to see the top 50 suppliers based on their total value (e.g. Actual £ Total) and then all the Concessions (as per your first screenshot) ?
If so, you will need to rank the suppliers by their total and select any that are rank 50 or below.
Here's a very simplified example that might help. In this I've used SUM() OVER() rather than using GROUP BY but this means you might want to change the SELECT to SELECT DISTINCT depending on you needs as you will get lots of duplicate rows. Obviously it's not got your lengthy case statements in but you should be able to adapt it easily.
SELECT * FROM
(
SELECT
x.*
, DENSE_RANK() OVER(ORDER BY SupplierTotal DESC) as SupplierRank
, DENSE_RANK() OVER(PARTITION BY SupplierID ORDER BY ConcessionTotal DESC) as ConcessionRank
FROM
( SELECT DISTINCT
SupplierID, ConcessionID, MyOtherRequiredColumns,
SUM(myValue) OVER(PARTITION BY SupplierID) AS SupplierTotal,
SUM(myValue) OVER(PARTITION BY SupplierID, ConcessionID) AS ConcessionTotal
FROM MyTable
) x
) z
WHERE SupplierRank <= 50
This will also rank the concessions within supplier which might be useful..
You will also have to change you report where you have summed the values up (e.g. 99,389 in Actual £ column). Instead of summing the rows below, change the expression to be =FIRST(Fields!SupplierTotal.Value)

SSRS - Row visibility expression

I am using SSRS 2014.
I want to display only first 50 rows. What will be the expression for this please.
I used top n functionality it doesn't work. So I thought to take another route to achieve the result via expression.
Below image with out adding 'top n'. In the below image I wanted to display only first 50 rows in Supplier column
Below image with adding 'top n'. Then results are changed. Few rows in Concession column are missing.
SQL code is,
SELECT s.[CusNo] Supplier,
RTRIM(CAST(s.[Customer] AS VARCHAR(50)) ) AS Name,
s.[ConcessionNo] Concession,
RTRIM(CAST(s.[ConcessionName] AS VARCHAR(50)) ) AS ConcessionName,
sum(case when s.Date between convert(date,dateadd(wk, datediff(wk, 0, getdate()) - 1, 0) - 1) and convert(date,dateadd(wk, datediff(wk, 0, getdate()) - 1, 0) + 5)
then s.SELLINC else 0 end) ActualSales,
sum(case when s.Date
BETWEEN
convert(varchar(10), DATEADD(day, DATEDIFF(day, '19000107', DATEADD(month, DATEDIFF(MONTH, 0, CONVERT(date, CONVERT(VARCHAR(4), (CASE WHEN MONTH(GetDate()) = 1 THEN CONVERT(VARCHAR(4), GetDate(), 112) - 1 ELSE CONVERT(VARCHAR(4), GetDate(), 112) END), 112) + '0101')), 30)) / 7 * 7, '19000107'), 120)
AND
Convert(date, dateadd(wk, datediff(wk, 0, GETDATE()) - 1, 0) + 5)
then s.SELLINC else 0 end) YrToDateActual
FROM [dbo].[CustomerReports] s
WHERE s.BRN = 1 or s.BRN = 2 or s.BRN = 3 or s.BRN = 4 or s.BRN = 5 or s.SELLINC is null or s.SELLINC = '0'
GROUP BY s.[CusNo], s.[Customer], s.ConcessionNo, s.ConcessionName
order by YrToDateActual desc
Any help please?
If you want the first 50 suppliers, you should be able to use the following expression in the row visibility property:
=RunningValue(Fields!Supplier.Value, CountDistinct,"YourDataset") > 50
The report should perform better if you put this expression as a filter on the group instead of a row visibility expression, but at the moment I can't test to confirm whether this expression would be allowed there.
Modify your ORDER BY clause to:
ORDER BY s.[CusNo], YrToDateActual desc

Obtaining columns values only if date > today

I have a query where i need to get values in 4 columns but only if the date is greater than today from a 5th column. I have tried the following but it doesn't seem to be working.
Select
(case when clientplans.END_DATE < convert(date,getdate(,101) then '') else insplans.Desc_upper as PLAN NAME,
(case when clientplans.END_DATE < convert(date,getdate(,112) then '') else insplans.ID_NO,
(case when clientplans.END_DATE < convert(date,getdate(,112) then '') else insplans.cert_NO,
I have converted the date on the end date as follows:
convert (varchar,clientplans.END_DATE,112) as POLICY_EXP_DATE,
does it matter that I do the conversion of the end date later in the query? the clientplans.end_date has to be inserted into the results in a certain order which happens to be after the description, id and cert number. Thanks for any help.
Perhaps something like this does what you want:
Select (case when cp.END_DATE > cast(getdate() as date) then insplans.Desc_upper end) as PLAN_NAME,
(case when cp.END_DATE > cast(getdate() as date) then insplans.ID_NO end) as ID_NO,
(case when cp.END_DATE > cast(getdate() as date) then insplans.cert_NO END) as cert_NO
from clientplans cp . . .
Note the following:
This table uses table aliases (cp for clientplans), so the query is easier to write and to read.
It uses cast() to a date to just get the date.
Non-matching rows are given a NULL value instead of ''. That usually makes more sense.
EDIT:
Of course, you can use '', if you like:
Select (case when cp.END_DATE > cast(getdate() as date) then insplans.Desc_upper else '' end) as PLAN_NAME,
(case when cp.END_DATE > cast(getdate() as date) then insplans.ID_NO else '' end) as ID_NO,
(case when cp.END_DATE > cast(getdate() as date) then insplans.cert_NO else '' end) as cert_NO,
(case when cp.END_DATE > cast(getdate() as date)
then convert(varchar(255), cp.StartDate, 121) else ''
end) as StartDate
from clientplans cp . . .
Use this to get the start of today: DATEADD(day, DATEDIFF(day, 0, GETDATE()), 0)
For example:
SELECT DATEADD(day, DATEDIFF(day, 0, GETDATE()), 0)
And for yours...
Select
(case when clientplans.END_DATE > DATEADD(day, DATEDIFF(day, 0, GETDATE()), 0) then '') else insplans.Desc_upper as PLAN NAME,
(case when clientplans.END_DATE > DATEADD(day, DATEDIFF(day, 0, GETDATE()), 0) then '') else insplans.ID_NO,
(case when clientplans.END_DATE > DATEADD(day, DATEDIFF(day, 0, GETDATE()), 0) then '') else insplans.cert_NO,
i think proper casting is required So I Used Here CAST(Field as DATE) and
in Your Query getdate(,101) is wrong syntax
Select
(case when CAST(clientplans.END_DATE as date) < CAST(getdate() as date) then '')
else insplans.Desc_upper as PLAN NAME,
(case when CAST(clientplans.END_DATE as date) < CAST(getdate() as date) then '')
else insplans.ID_NO,
(case when CAST(clientplans.END_DATE as date) < CAST(getdate() as date) then '')
else insplans.cert_NO
You can use cursor on the 5th column
and check #cursor_date> is greater than today.
Only then will get the rest of the 4 columns.

SQL Server: better / faster way of combining multiple counts in select

I am using the below stored procedure in order to combine multiple counts.
This works fine so far and returns the following XML, i.e. a count of records for each of the last 6 months.
As I am pretty new to SQL and all these counts are done on the same table I was wondering if there is a better / faster way to achieve the same.
Example result (XML):
<ranks>
<groupCount>18</groupCount>
<groupCount>15</groupCount>
<groupCount>21</groupCount>
<groupCount>13</groupCount>
<groupCount>15</groupCount>
<groupCount>19</groupCount>
</ranks>
My stored procedure:
BEGIN
SET NOCOUNT ON;
SELECT COUNT(*) AS groupCount
FROM Log_PE
WHERE CONVERT(DATE, dateEsc, 120) >= CONVERT(DATE, CONVERT(VARCHAR(6), GETDATE(), 112) + '01', 112)
UNION ALL
SELECT COUNT(*) AS groupCount
FROM Log_PE
WHERE CONVERT(DATE, dateEsc, 120) >= CONVERT(DATE, CONVERT(VARCHAR(6), DATEADD(month, -1, GETDATE()), 112) + '01', 112)
UNION ALL
SELECT COUNT(*) AS groupCount
FROM Log_PE
WHERE CONVERT(DATE, dateEsc, 120) >= CONVERT(DATE, CONVERT(VARCHAR(6), DATEADD(month, -2, GETDATE()), 112) + '01', 112)
UNION ALL
SELECT COUNT(*) AS groupCount
FROM Log_PE
WHERE CONVERT(DATE, dateEsc, 120) >= CONVERT(DATE, CONVERT(VARCHAR(6), DATEADD(month, -3, GETDATE()), 112) + '01', 112)
UNION ALL
SELECT COUNT(*) AS groupCount
FROM Log_PE
WHERE CONVERT(DATE, dateEsc, 120) >= CONVERT(DATE, CONVERT(VARCHAR(6), DATEADD(month, -4, GETDATE()), 112) + '01', 112)
UNION ALL
SELECT COUNT(*) AS groupCount
FROM Log_PE
WHERE CONVERT(DATE, dateEsc, 120) >= CONVERT(DATE, CONVERT(VARCHAR(6), DATEADD(month, -5, GETDATE()), 112) + '01', 112)
FOR XML PATH(''), ROOT('ranks')
END
Many thanks for any help with this, Tim.
Your requirements seem to conflict with what you are doing in your SQL
select CONVERT(DATE, CONVERT(VARCHAR(6), GETDATE(), 112) + '01', 112)
will get the first day of the current month
select CONVERT(DATE, CONVERT(VARCHAR(6), GETDATE(), 112) + '02', 112)
will get the second day of the current month
To get the count of the last 6 complete months of records grouped by month
SELECT COUNT(*) AS groupCount
FROM Log_PE
WHERE dateEsc >= CAST(DATEADD(day, 1, DATEADD(month, -6, DATEADD(day, day(GETDATE())*-1, GETDATE()))) as DATE) --the first day of the month, 6 months ago
AND dateEsc < DATEADD(day, (day(GETDATE())*-1)+1, GETDATE()) -- the first day of current month
GROUP BY year(dateEsc), month(dateEsc)
ORDER BY year(dateEsc), month(dateEsc)
FOR XML PATH(''), ROOT('ranks')
Here is a SQL Fiddle: http://www.sqlfiddle.com/#!3/3ff71/7