Union Order By using different field SQL Server - sql

Im trying to sort below query by using Order By. However when im using MonthYear field the output result display as below which not sort accordingly by latest year and month.
Order By MonthYear Output.
MonthYear
2017/9
2017/8
2017/7
2017/6
2017/5
2017/4
2017/10
So I want to try by order by year and month but i cant do it since another query after union all line has different field which is a.created_year. Is there any way I can do it?
SELECT CONVERT(varchar, A.YEAR) + '/' + CONVERT(varchar, A.MONTH)AS MonthYear
FROM PAY_Previous AS A LEFT OUTER JOIN
EMPLOYEE_BADGE AS B ON A.EMPLOYEE_NO = B.EMPLOYEE_NO LEFT OUTER JOIN
V_EMPLOYEE_PROFILES AS C ON A.EMPLOYEE_NO = C.EMPLOYEE_NO
WHERE A.EMPLOYEE_NO = '710049' AND A.FREQUENCY = 2 and (day(getdate())>=28 or month(getdate()) > a.Month or YEAR(getdate()) > A.YEAR )
UNION ALL-
SELECT CONVERT(varchar, YEAR(A.CREATED_DATE)) + '/' + CONVERT(varchar, A.MONTH) AS MonthYear
FROM PAY_Current AS A LEFT OUTER JOIN
EMPLOYEE_BADGE AS B ON A.EMPLOYEE_NO = B.EMPLOYEE_NO LEFT OUTER JOIN
V_EMPLOYEE_PROFILES AS C ON A.EMPLOYEE_NO = C.EMPLOYEE_NO
WHERE A.EMPLOYEE_NO = '710049'AND A.FREQUENCY = 2 and (day(getdate())>=28 or month(getdate()) > a.Month or YEAR(getdate()) > A.CREATED_DATE )
ORDER BY YEAR(A.CREATED_DATE) DESC ,A.MONTH DESC
Expected Output
MonthYear
2017/10
2017/9
2017/8
2017/7
2017/6
2017/5
2017/4

Leave the data numeric until the last moment, then convert just the smallest list for presentation, and this leave the numeric columns available for ordering the result.
SELECT CONVERT(varchar, d.[YEAR]) + '/' + CONVERT(varchar, d.[MONTH]) AS MonthYear
FROM
SELECT
A.[YEAR] , A.[MONTH]
FROM PAY_Previous AS A
LEFT OUTER JOIN EMPLOYEE_BADGE AS B ON A.EMPLOYEE_NO = B.EMPLOYEE_NO
LEFT OUTER JOIN V_EMPLOYEE_PROFILES AS C ON A.EMPLOYEE_NO = C.EMPLOYEE_NO
WHERE A.EMPLOYEE_NO = '710049'
AND A.FREQUENCY = 2
AND (DAY(GETDATE()) >= 28
OR MONTH(GETDATE()) > a.Month
OR YEAR(GETDATE()) > A.YEAR)
UNION
SELECT
YEAR(A.CREATED_DATE) [Year] , A.[MONTH]
FROM PAY_Current AS A
LEFT OUTER JOIN EMPLOYEE_BADGE AS B ON A.EMPLOYEE_NO = B.EMPLOYEE_NO
LEFT OUTER JOIN V_EMPLOYEE_PROFILES AS C ON A.EMPLOYEE_NO = C.EMPLOYEE_NO
WHERE A.EMPLOYEE_NO = '710049'
AND A.FREQUENCY = 2
AND (DAY(GETDATE()) >= 28
OR MONTH(GETDATE()) > a.Month
OR YEAR(GETDATE()) > A.CREATED_DATE)
) d
ORDER BY d.[YEAR] DESC, d.[MONTH] DESC
btw: Both "YEAR" and "MONTH" are terms used by T-SQL and it is not a good idea to use them as columns names.
IF, you need the result in a form that can reliably be re-ordered, then perhaps you could consider using a leading zero for the month number. e.g.
CONVERT(varchar(4), d.[YEAR]) + '/' + RIGHT('0' + CONVERT(varchar(2), d.[MONTH]),2) AS MonthYear
Which would look like this (and sort correctly)
2017/10
2017/04
2017/03
2017/02
2017/01
2016/10
2016/05

You are probably having a sort problem because you are using Created_Date to sort, but you are using different fields for MonthYear between statements.
Try this:
select MonthYear from (
SELECT CONVERT(varchar, A.YEAR) + '/' + CONVERT(varchar, A.MONTH)AS MonthYear, A.YEAR yr, A.MONTH mon
FROM PAY_Previous AS A LEFT OUTER JOIN
EMPLOYEE_BADGE AS B ON A.EMPLOYEE_NO = B.EMPLOYEE_NO LEFT OUTER JOIN
V_EMPLOYEE_PROFILES AS C ON A.EMPLOYEE_NO = C.EMPLOYEE_NO
WHERE A.EMPLOYEE_NO = '710049' AND A.FREQUENCY = 2 and (day(getdate())>=28 or month(getdate()) > a.Month or YEAR(getdate()) > A.YEAR )
UNION ALL
SELECT CONVERT(varchar, YEAR(A.CREATED_DATE)) + '/' + CONVERT(varchar, A.MONTH) AS MonthYear. YEAR(A.CREATED_DATE)) yr, CONVERT(varchar, A.MONTH) mon
FROM PAY_Current AS A LEFT OUTER JOIN
EMPLOYEE_BADGE AS B ON A.EMPLOYEE_NO = B.EMPLOYEE_NO LEFT OUTER JOIN
V_EMPLOYEE_PROFILES AS C ON A.EMPLOYEE_NO = C.EMPLOYEE_NO
WHERE A.EMPLOYEE_NO = '710049'AND A.FREQUENCY = 2 and (day(getdate())>=28 or month(getdate()) > a.Month or YEAR(getdate()) > A.CREATED_DATE )
)x
ORDER BY yr DESC, mon DESC

Related

sqlite return subquery multi column

I have a sqlite subquery with the following query which is calculating the hours and labour_rate. The only issue I now have is can I get the two columns from my subquery to output in the main query. I've tried to layout the query according to some of the web tutorials but need that little bit of help to get me over the finish line as I keep getting a syntax error
SELECT c.customerID, c.customer, sum( ifnull(il.line_price, 0 ) )/10000 AS net,
FROM customer AS c
LEFT JOIN invoice AS i
ON c.customerID = i.customerID
LEFT JOIN invoice_line AS il
ON i.invoiceID = il.invoiceID
(SELECT sum(( ifnull(tl.mon,0) + ifnull(tl.tues,0) + ifnull(tl.wed,0) + ifnull(tl.thurs,0) + ifnull(tl.fri,0) + ifnull(tl.sat,0) + ifnull(tl.sun,0) ) * s.cost_rate)/10000 AS labour_rate,
sum(( ifnull(tl.mon,0) + ifnull(tl.tues,0) + ifnull(tl.wed,0) + ifnull(tl.thurs,0) + ifnull(tl.fri,0) + ifnull(tl.sat,0) + ifnull(tl.sun,0) ))/10000 AS
FROM timesheet_line AS tl
LEFT JOIN timesheet AS t
ON tl.timesheetID = t.timesheetID
LEFT JOIN staff AS s
ON t.staffID = s.staffID
WHERE (c.customerID = tl.customerID) AND (t.date BETWEEN '2014-03-01' AND '2015-12-01')
GROUP BY tl.customerID) AS time1
WHERE (i.date BETWEEN '2014-03-01' AND '2015-12-01') AND (time1.customerID = tl.customerID)
GROUP BY c.customerID
ORDER BY c.customer ASC
There are a few syntax errors in here. The first (and possibly most important) is you have to JOIN your subquery to the rest of the result set. So after
LEFT JOIN invoice_line AS il
ON i.invoiceID = il.invoiceID
you will need to add another JOIN statement:
LEFT JOIN
(SELECT
SUM(...) AS labour_rate,
SUM(...) AS hours,
tl.customerID
FROM
...) AS time1
ON <your join condition>
You will have to select some sort of field in your sub query that you can join back to the the invoice on i.e. tl.customerID.
Also, in your subquery you cannot reference a field that is outside of it, so where you have WHERE (c.customerID = tl.customerID) in your subquery it will fail because you are trying to reference c.<fieldname>. It needs to be moved to the ON part of the JOIN clause. Once you get your JOIN working correctly then you can just change your outer-most SELECT to something like
SELECT c.customerID, c.customer, sum(ifnull(il.line_price,0))/10000 AS net, time1.labour_rate, time1.hours
Here's an example of how I would do it:
SELECT c.customerID, c.customer, sum( ifnull(il.line_price, 0 ) )/10000 AS net, time1.labour_rate, time1.[hours]
FROM customer AS c
LEFT JOIN invoice AS i
ON c.customerID = i.customerID
LEFT JOIN invoice_line AS il
ON i.invoiceID = il.invoiceID
LEFT JOIN
(SELECT
sum(( ifnull(tl.mon,0) + ifnull(tl.tues,0) + ifnull(tl.wed,0) + ifnull(tl.thurs,0) + ifnull(tl.fri,0) + ifnull(tl.sat,0) + ifnull(tl.sun,0) ) * s.cost_rate)/10000 AS labour_rate,
sum(( ifnull(tl.mon,0) + ifnull(tl.tues,0) + ifnull(tl.wed,0) + ifnull(tl.thurs,0) + ifnull(tl.fri,0) + ifnull(tl.sat,0) + ifnull(tl.sun,0) ))/10000 AS [hours],
tl.customerID
FROM timesheet_line AS tl
LEFT JOIN timesheet AS t
ON tl.timesheetID = t.timesheetID
LEFT JOIN staff AS s
ON t.staffID = s.staffID
WHERE (t.date BETWEEN '2014-03-01' AND '2015-12-01')
GROUP BY tl.customerID) AS time1
ON c.customerID = time1.customerID
WHERE (i.date BETWEEN '2014-03-01' AND '2015-12-01')
GROUP BY c.customerID
ORDER BY c.customer ASC

How to get the MAX() while NOT grouping all columns in SQL Server

I have this query.
The INNER SELECT brings back multiple records. The outer does a SUM & MAX so I only have 1 record:
SELECT z.EmployeeId,
SUM(z.PayrollGap) AS PayrollGap,
MAX(z.PayrollGap) AS PayrollGapMax
FROM (SELECT DISTINCT
a.EmployeeId,
a.PayPeriodStart,
a.PayPeriodEnd,
b.PayPeriodStart AS NextStartDate,
CASE WHEN DATEDIFF(d, a.PayPeriodEnd, b.PayPeriodStart) - 1 < 0 THEN 0
ELSE DATEDIFF(d, a.PayPeriodEnd, b.PayPeriodStart) - 1
END AS PayrollGap
FROM EmployeePayroll a
LEFT JOIN EmployeePayroll b
ON b.EmployeeId = a.EmployeeId
AND b.rn = a.rn + 1
WHERE b.PayPeriodStart IS NOT NULL) z
GROUP BY z.EmployeeId
Along with the MAX(z.PayrollGap), I need to grab the PayPeriodStart as well.
The problem is that if I add the column PayPeriodStart to the query, it'll bring back more than 1 record and I need to do a MAX(z.PayrollGap).
How do I go about running this query but at the same time bringing back the PayPeriodStart RELATED TO MAX(z.PayrollGap)?
Try to split query:
;with cte as
(
SELECT DISTINCT
a.EmployeeId,
a.PayPeriodStart,
a.PayPeriodEnd,
b.PayPeriodStart AS NextStartDate,
CASE WHEN DATEDIFF(d, a.PayPeriodEnd, b.PayPeriodStart) - 1 < 0 THEN 0
ELSE DATEDIFF(d, a.PayPeriodEnd, b.PayPeriodStart) - 1
END AS PayrollGap
FROM EmployeePayroll a
LEFT JOIN EmployeePayroll b
ON b.EmployeeId = a.EmployeeId
AND b.rn = a.rn + 1
WHERE b.PayPeriodStart IS NOT NULL
),
res as
(
SELECT z.EmployeeId,
SUM(z.PayrollGap) AS PayrollGap,
MAX(z.PayrollGap) AS PayrollGapMax
FROM cte z
GROUP BY z.EmployeeId
)
select r.EmployeeId, r.PayrollGap, r.PayrollGapMax, c.PayPeriodStart
from res r
join cte c on c.EmployeeId = r.EmployeeId
and c.PayrollGap = r.PayrollGapMax
If I understand the question correctly you need to join your result set back to EmployeePayroll to add in PayPeriodStart.
Something like:
WITH cte AS (
SELECT DISTINCT
a.EmployeeId,
a.PayPeriodStart,
a.PayPeriodEnd,
b.PayPeriodStart AS NextStartDate,
CASE WHEN DATEDIFF(d, a.PayPeriodEnd, b.PayPeriodStart) - 1 < 0 THEN 0
ELSE DATEDIFF(d, a.PayPeriodEnd, b.PayPeriodStart) - 1
END AS PayrollGap
FROM EmployeePayroll a
LEFT JOIN EmployeePayroll b
ON b.EmployeeId = a.EmployeeId
AND b.rn = a.rn + 1
WHERE b.PayPeriodStart IS NOT NULL
)
SELECT EmployeeId
,PayrollGap
,PayrollGapMax
,PayPeriodStart
FROM (SELECT z.EmployeeId,
SUM(z.PayrollGap) AS PayrollGap,
MAX(z.PayrollGap) AS PayrollGapMax
FROM cte z
GROUP BY z.EmployeeId) x
INNER JOIN
cte ON cte.EmployeeId = x.EmployeeId
AND cte.PayrollGap = x.PayrollGapMax
Which isn't optimized.
Or tested, since no sample data.
Or formatted particularly nicely.
Try:
select distinct A.EmployeeId, A.PayrollGap, A.PayrollGapMax, B.PayPeriodStart
(SELECT z.EmployeeId,
SUM(z.PayrollGap) AS PayrollGap,
MAX(z.PayrollGap) AS PayrollGapMax
FROM (SELECT DISTINCT
a.EmployeeId,
a.PayPeriodStart,
a.PayPeriodEnd,
b.PayPeriodStart AS NextStartDate,
CASE WHEN DATEDIFF(d, a.PayPeriodEnd, b.PayPeriodStart) - 1 < 0 THEN 0
ELSE DATEDIFF(d, a.PayPeriodEnd, b.PayPeriodStart) - 1
END AS PayrollGap
FROM EmployeePayroll a
LEFT JOIN EmployeePayroll b
ON b.EmployeeId = a.EmployeeId
AND b.rn = a.rn + 1
WHERE b.PayPeriodStart IS NOT NULL) z
GROUP BY z.EmployeeId) A
inner join
(SELECT DISTINCT
a.EmployeeId,
a.PayPeriodStart,
a.PayPeriodEnd,
b.PayPeriodStart AS NextStartDate,
CASE WHEN DATEDIFF(d, a.PayPeriodEnd, b.PayPeriodStart) - 1 < 0 THEN 0
ELSE DATEDIFF(d, a.PayPeriodEnd, b.PayPeriodStart) - 1
END AS PayrollGap
FROM EmployeePayroll a
LEFT JOIN EmployeePayroll b
ON b.EmployeeId = a.EmployeeId
AND b.rn = a.rn + 1
WHERE b.PayPeriodStart IS NOT NULL) B
ON A.EmployeeId=B.EmployeeId and B.PayrollGap=A.PayrollGapMax

Top 1 Item from the List in SQL

I have the following scenario
I am getting Output like this
Month Product Name Amount
Jan-2014 A-Prodcut 50
Jan-2014 B-Product 45
Jan-2014 C-Product 55
Feb-2014 A-Prodcut 60
Feb-2014 B-Product 48
Feb-2014 C-Product 80
I want Output like this :
Jan-2014 C-Product 55
Feb-2014 C-Product 80
I want top product from each month How to achieve this
Here is my query
;With cte as
(
SELECT #EndDate AS TheMonth, 0 as [Counter]
UNION ALL
SELECT DATEADD(mm,-[Counter] -1,#EndDate), Counter + 1 AS TheMonth
from cte
WHERE DATEADD(mm,-[Counter] -1,#EndDate) >= #StartDate
)
SELECT
left(DATENAME(MM,TheMonth),3) +'-'+ cast(year(TheMonth) as varchar) AS [Month-Year],
ISNULL(IM.product_name,'N/A') as 'Product Name',
isnull(sum((ism.selling_price * siim.qty) + (((tm.tax_amount*(ism.selling_price * siim.qty))/100))),0) AS Amount
FROM
cte
LEFT OUTER JOIN RS_Sell_Order_Master AS SM on MONTH(invoice_date) = MONTH(TheMonth)
AND YEAR(invoice_date) = YEAR(TheMonth)
AND sm.is_approved = 1
LEFT OUTER JOIN RS_Sells_Invoice_Info_Master AS SIIM ON SM.sell_order_no = SIIM.sell_order_no
LEFT OUTER JOIN RS_Inventory_Master AS IM ON SIIM.product_id = IM.product_id
LEFT OUTER JOIN RS_Tax_Master AS TM ON TM.tax_id = SIIM.tax_id
LEFT OUTER JOIN RS_Inventory_Selling_Master AS ISM ON ISM.selling_product_id = SIIM.selling_product_id
GROUP BY
IM.product_name,
TheMonth
Use Row_number() in the select query ie.
SELECT MONTH, PRODUCT_NAME, AMOUNT
FROM (
SELECT MONTH, PRODUCT_NAME, AMOUNT,
ROW_NUMBER ( )
OVER (PARTITION BY Month order by amount Desc) AS RANK
)
WHERE RANK = 1
Hope this helps..
Try this:
SELECT *
FROM
(
SELECT [Month-Year], [Product Name], Amount, ROW_NUMBER() OVER (Partition BY [Month-Year] ORDER BY Amount DESC) as rn
FROM
(
SELECT
left(DATENAME(MM,TheMonth),3) +'-'+ cast(year(TheMonth) as varchar) AS [Month-Year],
ISNULL(IM.product_name,'N/A') as 'Product Name',
isnull(sum((ism.selling_price * siim.qty) + (((tm.tax_amount*(ism.selling_price * siim.qty))/100))),0) AS Amount
FROM
cte
LEFT OUTER JOIN RS_Sell_Order_Master AS SM on MONTH(invoice_date) = MONTH(TheMonth)
AND YEAR(invoice_date) = YEAR(TheMonth)
AND sm.is_approved = 1
LEFT OUTER JOIN RS_Sells_Invoice_Info_Master AS SIIM ON SM.sell_order_no = SIIM.sell_order_no
LEFT OUTER JOIN RS_Inventory_Master AS IM ON SIIM.product_id = IM.product_id
LEFT OUTER JOIN RS_Tax_Master AS TM ON TM.tax_id = SIIM.tax_id
LEFT OUTER JOIN RS_Inventory_Selling_Master AS ISM ON ISM.selling_product_id = SIIM.selling_product_id
GROUP BY
IM.product_name,
TheMonth
) a
)b
WHERE rn = 1
Usually OUTER APPLY or CROSS APPLY is a way to go in theese situations.
So your SELECT would be like this:
;With cte as
(
SELECT #EndDate AS TheMonth, 0 as [Counter]
UNION ALL
SELECT DATEADD(mm,-[Counter] -1,#EndDate), Counter + 1 AS TheMonth
from cte
WHERE DATEADD(mm,-[Counter] -1,#EndDate) >= #StartDate
)
SELECT
left(DATENAME(MM,TheMonth),3) +'-'+ cast(year(TheMonth) as varchar) AS [Month-Year],
'Product Name', Amount
FROM
cte
OUTER APPLY ( SELECT TOP 1
ISNULL(IM.product_name,'N/A') as 'Product Name',
isnull(sum((ism.selling_price * siim.qty) +
(((tm.tax_amount*(ism.selling_price * siim.qty))/100))),0) AS Amount
FROM RS_Sell_Order_Master AS SM
LEFT OUTER JOIN RS_Sells_Invoice_Info_Master AS SIIM
ON SM.sell_order_no = SIIM.sell_order_no
LEFT OUTER JOIN RS_Inventory_Master AS IM
ON SIIM.product_id = IM.product_id
LEFT OUTER JOIN RS_Tax_Master AS TM
ON TM.tax_id = SIIM.tax_id
LEFT OUTER JOIN RS_Inventory_Selling_Master AS ISM
ON ISM.selling_product_id = SIIM.selling_product_id
WHERE MONTH(invoice_date) = MONTH(TheMonth) AND YEAR(invoice_date) = YEAR(TheMonth) AND sm.is_approved = 1
ORDER BY Amount DESC
) x
GROUP BY
'Product Name',
TheMonth

Looking at SQL Code for Validation

I have two queries that appear to be the same. We are trying to get quarter today. One using a hard coded date and one not. One query is returning 2100 less records. The first and last record are the same. All of Feb match in both and the last 5 days in January match too.
Query 1 with hard coded date.
SELECT c.Account_RecordType
,timewait
,a.convotime
,DATENAME(Month, timewait) AS 'Mnth'
,DATENAME(year, timewait) AS 'yr'
,DATENAME(quarter, timewait) AS 'qrt'
FROM SalesForce.dbo.SalesForceContact AS b
INNER JOIN Dossier_Replication.dbo.vwSF_DATA_Contact c
ON b.ContactID = c.CONTACTID__C
RIGHT OUTER JOIN satVRS.dbo.rptNECACallHistory AS a
ON b.UserID = a.UserID_Caller
WHERE ( b.Platform = 'HandsonVRS' )
AND ( a.timeWait BETWEEN '2014-01-01' AND '2014-02-24' )
AND ( a.isReport = '1' )
AND ( a.NECA_isReport = '1' )
AND ( a.ConvoTime > '0' )
AND ( c.Account_RecordType = 'Enterprise Account' )
GROUP BY c.Account_RecordType
,timewait
,a.convotime
Second query is pulling quarter,year, and day from the date field in question.
SELECT c.Account_RecordType
,timewait
,a.convotime
,DATENAME(Month, timewait) AS 'Mnth'
,DATENAME(year, timewait) AS 'yr'
,DATENAME(quarter, timewait) AS 'qrt'
FROM SalesForce.dbo.SalesForceContact AS b
INNER JOIN Dossier_Replication.dbo.vwSF_DATA_Contact c
ON b.ContactID = c.CONTACTID__C
RIGHT OUTER JOIN satVRS.dbo.rptNECACallHistory AS a
ON b.UserID = a.UserID_Caller
WHERE ( b.Platform = 'HandsonVRS' )
AND ( a.timeWait BETWEEN '2014-01-01' AND '2014-02-24' )
AND ( a.isReport = '1' )
AND ( a.NECA_isReport = '1' )
AND ( a.ConvoTime > '0' )
AND ( c.Account_RecordType = 'Enterprise Account' )
GROUP BY c.Account_RecordType
,timewait
,a.convotime
Does any one see anything obviously wrong with these two. Any suggestions, I thank you in advance. We are running sql 2012
Sorry my bad, here is the second one...
select
c.Account_RecordType,timewait,a.convotime,(datename(year,timewait))as twy,(datename(quarter,timewait))as twq
FROM SalesForce.dbo.SalesForceContact AS b INNER JOIN
Dossier_Replication.dbo.vwSF_DATA_Contact c ON b.ContactID = c.CONTACTID__C RIGHT OUTER JOIN
satVRS.dbo.rptNECACallHistory AS a ON b.UserID = a.UserID_Caller
WHERE (b.Platform = 'HandsonVRS')
AND (datename(year,timewait))=(datename(year,getdate()-1)) AND (datename(quarter,timewait))=(datename(quarter,getdate()-1))
AND (a.isReport = '1')
AND (a.NECA_isReport = '1')
AND (a.ConvoTime > '0')
AND (c.Account_RecordType = 'Enterprise Account')
Group by c.Account_RecordType,timewait,a.convotime
Order by timewait

How do I use a SELECT ... AS in a WHERE clause

Here is a piece of SQL code that does not work:
SELECT bl.regn_id,
RTRIM(LTRIM(dv.dv_id)) + '_' + RTRIM(LTRIM(bl.regn_id)) AS bu_regn,
(SELECT COUNT (em.em_id)
FROM em
LEFT OUTER JOIN bl bl_s ON em.bl_id = bl_s.bl_id
LEFT OUTER JOIN irs_self_cert_em ON em.em_id = irs_self_cert_em.em_id
WHERE dv.dv_id = em.dv_id
AND bl.bl_id = bl_s.bl_id
AND irs_self_cert_em.date_cert_loc >= DATEADD(month, -1, GETDATE())
AND (em.date_last_update_cads >= (select date_last_update_completed FROM ddi_completed WHERE ddi_id='TRA_CADS_EM'))
) AS certified
FROM bl
CROSS JOIN dv
WHERE bl.status = 'A' AND (certified > 0 )
I receive the error: "Lookup Error - SQL Server Database Error: Invalid column name 'certified'."
As you can see I use a subquery within the SELECT statement and give it the name 'certified'. I then try to use that value in the WHERE clause.
Can someone suggest and alternative way of accomplishing this?
Many thanks,
Matt
You can not use an aliased (calculated) column in a WHERE clause. I would create another subquery to add criteria to that field.
SELECT * FROM
(
SELECT
bl.regn_id,
RTRIM(LTRIM(dv.dv_id)) + '_' + RTRIM(LTRIM(bl.regn_id)) AS bu_regn,
(
SELECT
COUNT(em.em_id) AS [Count]
FROM
em LEFT OUTER JOIN bl AS bl_s
ON
em.bl_id = bl_s.bl_id LEFT OUTER JOIN irs_self_cert_em
ON
em.em_id = irs_self_cert_em.em_id
WHERE
dv.dv_id = em.dv_id
AND
bl.bl_id = bl_s.bl_id
AND
irs_self_cert_em.date_cert_loc >= DATEADD(month, -1, GETDATE())
AND
(em.date_last_update_cads >= (select date_last_update_completed FROM ddi_completed WHERE ddi_id='TRA_CADS_EM'))
) AS certified
FROM
bl CROSS JOIN dv
WHERE
bl.status = 'A'
) AS temp
WHERE
certified > 0
I also tried to clean up the query a bit. You were using LEFT OUTER JOINs with criteria on the right had side table, so it was truly an INNER JOIN (INNER JOINs will work more efficiently / quickly). Check it out and let me know if this works for you as expected.
;WITH
cte AS
(
SELECT
bl.regn_id,
RTRIM(LTRIM(dv.dv_id)) + '_' + RTRIM(LTRIM(bl.regn_id)) AS bu_regn
COUNT(*) OVER (PARTITION BY bl.regn_id, dv.dv_id, bl.regn_id ORDER BY bl.regn_id) AS [Certified]
FROM
dv INNER JOIN em
ON
dv.dv_id = em.dv_id INNER JOIN JOIN bl
ON
em.bl_id = bl.bl_id INNER JOIN JOIN irs_self_cert_em
ON
em.em_id = irs_self_cert_em.em_id
WHERE
bl.status = N'A'
AND
irs_self_cert_em.date_cert_loc >= DATEADD(month, -1, GETDATE())
AND
(em.date_last_update_cads >= (select date_last_update_completed FROM ddi_completed WHERE ddi_id='TRA_CADS_EM')
)
SELECT
DISTINCT
*
FROM
cte
WHERE
Certified > 0
Without having tables structure (ex: to know which id is unique) some data related to them and the way you want the output, it's hard to say and test but I went with something that look like this :
SELECT bl.regn_id,
RTRIM(LTRIM(dv.dv_id)) + '_' + RTRIM(LTRIM(bl.regn_id)) AS bu_regn,
result.certified
FROM bl
INNER JOIN
(SELECT em.bl_id AS bl_id, COUNT (em.em_id) as certified
FROM em
LEFT OUTER JOIN bl bl_s ON em.bl_id = bl_s.bl_id
INNER JOIN irs_self_cert_em ON em.em_id = irs_self_cert_em.em_id
AND irs_self_cert_em.date_cert_loc >= DATEADD(month, -1, GETDATE())
GROUP BY em.bl_id
HAVING COUNT (em.em_id) > 0
) AS result ON result.bl_id = bl.bl_id
INNER JOIN em ON result.bl_id = em.bl_id
AND (em.date_last_update_cads >=
(SELECT date_last_update_completed FROM ddi_completed WHERE ddi_id='TRA_CADS_EM'))
CROSS JOIN dv ON dv.dv_id = em.dv_id
WHERE bl.status = 'A'
SELECT bl.regn_id,
RTRIM(LTRIM(dv.dv_id)) + '_' + RTRIM(LTRIM(bl.regn_id)) AS bu_regn,
S.certified
FROM bl
CROSS JOIN dv
CROSS APPLY (SELECT COUNT (em.em_id) as certified
FROM em
LEFT OUTER JOIN bl bl_s ON em.bl_id = bl_s.bl_id
LEFT OUTER JOIN irs_self_cert_em ON em.em_id = irs_self_cert_em.em_id
WHERE dv.dv_id = em.dv_id
AND bl.bl_id = bl_s.bl_id
AND irs_self_cert_em.date_cert_loc >= DATEADD(month, -1, GETDATE())
AND (em.date_last_update_cads >= (select date_last_update_completed FROM ddi_completed WHERE ddi_id='TRA_CADS_EM'))
) AS S
WHERE bl.status = 'A' AND (S.certified > 0 )