Syntax error in Join Operation- MS Access inline join statement - sql

I am trying to run below query but I am getting error on MS Access, "Syntax error in Join Operation"
Below is my query -
select
v.City,
v.CURRENCY,
(
select
Sum(VSDEH.NORM_PRICE_MEDIUM*BCIEH.WEIGHT_OR_MULTIPLIER) AS BaseMedium
FROM (
// This line has error ->> ([VSURVEYDATA] AS VSDEH INNER JOIN [BASKET_CONTENT_ITEMS] AS BCIEH ON VSDEH.ITEM = BCIEH.ITEM_ID)
INNER JOIN [EXCHANGE_RATES] AS EXREH on VSDEH.SURVEY_DATE = EXREH.RATE_DATE AND VSDEH.CURRENCY = EXREH.BASE_CURRENCY_ID
)
WHERE (
VSDEH.SURVEY_DATE = v.SURVEY_DATE
AND BCIEH.LINE_OF_BUSINESS_ID='ICOL'
AND BCIEH.BASKET_ID= b.BASKET_ID
AND BCIEH.ITEM_ID not in ( '215','216','326')
AND EXREH.HOST_CURRENCY_ID= ex.HOST_CURRENCY_ID
AND EXREH.RATE_SET_ID=' '
AND VSDEH.CITY in (v.City)
)
GROUP BY VSDEH.CITY, VSDEH.CURRENCY
) as BaseMediumEH
FROM ((
([VSURVEYDATA] AS VSDEH INNER JOIN [BASKET_CONTENT_ITEMS] AS BCIEH ON VSDEH.ITEM = BCIEH.ITEM_ID)
INNER JOIN [EXCHANGE_RATES] AS EXREH on VSDEH.SURVEY_DATE = EXREH.RATE_DATE AND VSDEH.CURRENCY = EXREH.BASE_CURRENCY_ID
)
INNER JOIN qSTAHostCity ON VSURVEYDATA.CITY = qSTAHostCity.HostCity)
WHERE (
v.SURVEY_DATE = [Survey Date]
AND b.LINE_OF_BUSINESS_ID='ICOL'
AND b.BASKET_ID= [Basket ID]
AND ex.HOST_CURRENCY_ID='USD'
AND ex.RATE_SET_ID=' ')
GROUP BY v.CITY, v.CURRENCY ORDER BY v.CITY
Can anyone suggest what am I doing wrong here ?
Thanks

You miss two table alias :
Replace *****TableAlias***** by the table alias name you need to do your join.
select
v.City,
v.CURRENCY,
(
select
Sum(VSDEH.NORM_PRICE_MEDIUM*BCIEH.WEIGHT_OR_MULTIPLIER) AS BaseMedium
FROM (
// This line has error ->> ([VSURVEYDATA] AS VSDEH INNER JOIN [BASKET_CONTENT_ITEMS] AS BCIEH ON VSDEH.ITEM = BCIEH.ITEM_ID) *****TableAlias*****
INNER JOIN [EXCHANGE_RATES] AS EXREH on VSDEH.SURVEY_DATE = EXREH.RATE_DATE AND VSDEH.CURRENCY = EXREH.BASE_CURRENCY_ID
)
WHERE (
VSDEH.SURVEY_DATE = v.SURVEY_DATE
AND BCIEH.LINE_OF_BUSINESS_ID='ICOL'
AND BCIEH.BASKET_ID= b.BASKET_ID
AND BCIEH.ITEM_ID not in ( '215','216','326')
AND EXREH.HOST_CURRENCY_ID= ex.HOST_CURRENCY_ID
AND EXREH.RATE_SET_ID=' '
AND VSDEH.CITY in (v.City)
)
GROUP BY VSDEH.CITY, VSDEH.CURRENCY
) as BaseMediumEH
FROM ((
([VSURVEYDATA] AS VSDEH INNER JOIN [BASKET_CONTENT_ITEMS] AS BCIEH ON VSDEH.ITEM = BCIEH.ITEM_ID) *****TableAlias*****
INNER JOIN [EXCHANGE_RATES] AS EXREH on VSDEH.SURVEY_DATE = EXREH.RATE_DATE AND VSDEH.CURRENCY = EXREH.BASE_CURRENCY_ID
)
INNER JOIN qSTAHostCity ON VSURVEYDATA.CITY = qSTAHostCity.HostCity)
WHERE (
v.SURVEY_DATE = [Survey Date]
AND b.LINE_OF_BUSINESS_ID='ICOL'
AND b.BASKET_ID= [Basket ID]
AND ex.HOST_CURRENCY_ID='USD'
AND ex.RATE_SET_ID=' ')
GROUP BY v.CITY, v.CURRENCY ORDER BY v.CITY

Related

trying to modifying a multi join query with issues

I have a simplified query shown below, that does mulitple joins. I'm trying to add a field to be selected but I am unable to find a good way of joining it without changing the number of records that come up...
SELECT tblApp.AppID
,'Type' = tblRef.Label
,'Status' = tblRef2.Label
FROM (
(
(
tblApp LEFT JOIN tblAppExt ON tblApp.AppID = tblAppExt.AppID
) LEFT JOIN tblRef ON tblApp.AppTypeID = tblReferenceData.ID
) LEFT JOIN tblRef tblRef2 ON tblApp.AppStatusID = tblRef2.ID
)
As is - I'm getting 149 results, if I try to Join it in any way, I get like 10 time fold the number of records. All I'm hoping to do is be able to SELECt another field. I'm hoping to join tblAppExt2 that has AppID just like the other tables in the FROM part of the query, so my goal would basically be to do this:
SELECT tblApp.AppID
,'Type' = tblRef.Label
,'Status' = tblRef2.Label
,'NewField' = tblAppExt2.NewField
First thing to try is DISTINCT:
SELECT DISTINCT
tblApp.AppID
, [Type] = tblRef.Label
, [Status] = tblRef2.Label
, [NewField] = tblAppExt2.NewField
FROM tblApp
LEFT JOIN tblAppExt
ON tblApp.AppID = tblAppExt.AppID
LEFT JOIN tblRef
ON tblApp.AppTypeID = tblReferenceData.ID
LEFT JOIN tblRef tblRef2
ON tblApp.AppStatusID = tblRef2.ID
LEFT JOIN tblAppExt2.NewField
ON something = somethingElse ;
If that doesn't work, it means there are multiple different values for [NewField] and you'll need to tell it how to select the correct one. For example, to take the most recent [NewField] you can use a CTE with the ROW_NUMBER function:
; WITH AllRecords
AS (
SELECT DISTINCT
tblApp.AppID
, [Type] = tblRef.Label
, [Status] = tblRef2.Label
, [NewField] = tblAppExt2.NewField
, MyRank = ROW_NUMBER() OVER(PARTITION BY tblApp.ID ORDER BY tblAppExt2.DateEntered DESC)
FROM tblApp
LEFT JOIN tblAppExt
ON tblApp.AppID = tblAppExt.AppID
LEFT JOIN tblRef
ON tblApp.AppTypeID = tblReferenceData.ID
LEFT JOIN tblRef tblRef2
ON tblApp.AppStatusID = tblRef2.ID
LEFT JOIN tblAppExt2.NewField
ON something = somethingElse
)
SELECT *
FROM AllRecords
WHERE AllRecords.MyRank = 1 ;
You can use outer apply or correlated subquery :
SELECT tblApp.AppID, tblRef.Label as [Type], tblRef2.Label as [Status],
tappext.NewField
FROM tblApp tapp LEFT JOIN
tblAppExt tex
ON tapp.AppID = tex.AppID LEFT JOIN
tblRef tref
ON tapp.AppTypeID = tref.ID LEFT JOIN
tblRef tblRef2
ON tapp.AppStatusID = tblRef2.ID OUTER APPLY
( SELECT TOP (1) tappext.*
FROM tblAppExt2 tappext
WHERE tapp.AppID = AppID
ORDER BY ??
) tappext;

An SQL query with an 'IN' within the where clause is very slow to run

I have created an SQL query which runs but it takes about 17 seconds to complete. I have narrowed down the problem to the IN clause within the Where section of the query. This section is responsible for also finding all records within the same table where the kitref of one record matches the partofkit field of multiple other records.
Could anyone help with suggestions on how I may be able to make this more efficient?
The full SQL is below:
SELECT
tblProductions.ProductionName, tblEquipment.KitRef, tblEquipment.PartOfKit, tblEquipment.Description,
tblCollection.HireID, tblCollection.CollectedBy, Format(tblCollection.DueBack,'dd/MM/yyyy') AS DueBack, Format(tblCollection.CollectionDate,'dd/MM/yyyy') AS CollectionDate, Format(tblCollection.CollectionTime,'HH:mm') AS CollectionTime, tblCollection.DiscountPC,
tblCollectionItemized.HireLine, tblCollectionItemized.Notes, tblCollectionItemized.BookingActive, tblCollectionItemized.DepositReturned, tblTariff.Tariff
FROM tblTariff
INNER JOIN (
tblProductions INNER JOIN (
tblCollection INNER JOIN (
tblEquipment
INNER JOIN tblCollectionItemized ON tblEquipment.KitKey = tblCollectionItemized.KitKey
) ON tblCollection.HireID = tblCollectionItemized.HireID)
ON tblProductions.ProductionIDKey = tblCollection.ProductionName
) ON tblTariff.TariffKey = tblCollection.Tarriff
WHERE (
tblCollectionItemized.BookingActive='TRUE'
AND tblEquipment.PartOfKit IN (
SELECT tblEquipment.KitRef
FROM tblEquipment
INNER JOIN tblCollectionItemized ON tblEquipment.KitKey = tblCollectionItemized.KitKey
WHERE tblCollectionItemized.ReturnsNumber =43
)
)
OR (
tblCollectionItemized.BookingActive='TRUE'
AND tblCollectionItemized.ReturnsNumber =43
)
Not a complete answer here but using some aliases and joins in a logical order make this nightmarish query into something a lot easier to see what is going on.
SELECT
p.ProductionName
, e.KitRef
, e.PartOfKit
, e.Description
, c.HireID
, c.CollectedBy
, Format(c.DueBack,'dd/MM/yyyy') AS DueBack
, Format(c.CollectionDate,'dd/MM/yyyy') AS CollectionDate
, Format(c.CollectionTime,'HH:mm') AS CollectionTime
, c.DiscountPC
, ci.HireLine
, ci.Notes
, ci.BookingActive
, ci.DepositReturned
, t.Tariff
FROM tblTariff t
INNER JOIN tblCollection c ON t.TariffKey = c.Tarriff
INNER JOIN tblProductions p ON p.ProductionIDKey = c.ProductionName
INNER JOIN tblCollectionItemized ci ON c.HireID = ci.HireID
INNER JOIN tblEquipment e ON e.KitKey = ci.KitKey
WHERE ci.BookingActive = 'TRUE'
AND e.PartOfKit IN
(
SELECT e2.KitRef
FROM tblEquipment e2
INNER JOIN tblCollectionItemized ci2 ON e2.KitKey = ci2.KitKey
WHERE ci2.ReturnsNumber = 43
)
OR
(
ci.ReturnsNumber = 43
)
you can try EXISTS instead of IN and add (nolock) hint to tables
SELECT
P.ProductionName,
E.KitRef,
E.PartOfKit,
E.Description,
C.HireID,
C.CollectedBy,
Format(C.DueBack,'dd/MM/yyyy') AS DueBack,
Format(C.CollectionDate,'dd/MM/yyyy') AS CollectionDate,
Format(C.CollectionTime,'HH:mm') AS CollectionTime,
C.DiscountPC,
CI.HireLine,
CI.Notes,
CI.BookingActive,
CI.DepositReturned,
T.Tariff
FROM tblTariff T
INNER JOIN tblCollection C (nolock) ON T.TariffKey = C.Tarriff
INNER JOIN tblProductions P (nolock) ON P.ProductionIDKey = C.ProductionName
INNER JOIN tblCollectionItemized CI (nolock) ON C.HireID = CI.HireID
INNER JOIN tblEquipment E (nolock) ON E.KitKey = CI.KitKey
WHERE (
tblCollectionItemized.BookingActive='TRUE'
AND EXISTS (
SELECT *
FROM tblEquipment E2 (nolock)
INNER JOIN tblCollectionItemized CI2 (nolock) ON E2.KitKey = CI2.KitKey
WHERE CI2.ReturnsNumber =43 AND E.PartOfKit = E2.KitRef )
)
OR (
CI.BookingActive='TRUE'
AND CI.ReturnsNumber =43
)

Alternate way of Exists with Having clause

The below query is to retrieve the records whose (SGT_DISBURSEMENT_REQUEST) count is only one. It is working great. But performance wise it didn't took so much of time since we have 100 000 records.
Is there any better way to do it?
SELECT PA.PERSON_ID,
PA.PERSON_ACCOUNT_ID,
DR.DISBURSEMENT_REQUEST_ID,
SUM
(
ISNULL(CD.EE_PRE_TAX_AMT,0) +
ISNULL(CD.EE_ADDL_PRE_TAX_AMT,0)
) AS EE_PRE_TAX_CONTRIB,
DD.PRE_TAX_AMOUNT AS DISB_DTL_PRE_TAX_AMOUNT,
SUM
( ISNULL(CD.EE_POST_TAX_AMT,0) +
ISNULL(CD.EE_ADDL_POST_TAX_AMT,0)
) AS EE_POST_TAX_CONTRIB,
DD.POST_TAX_AMOUNT AS DISB_DTL_POST_TAX_AMOUNT
FROM SGT_DISBURSEMENT_REQUEST DR
INNER JOIN SGT_DISBURSEMENT_DETAIL DD ON DR.DISBURSEMENT_REQUEST_ID = DD.DISBURSEMENT_REQUEST_ID
INNER JOIN SGT_PERSON_ACCOUNT PA ON PA.PERSON_ACCOUNT_ID = DR.PERSON_ACCOUNT_ID
INNER JOIN SGT_CONTRIB_DTL CD ON CD.PERSON_ACCOUNT_ID = PA.PERSON_ACCOUNT_ID
WHERE DR.REQUEST_CATEGORY_VALUE = 'REFD' AND
DD.DETAIL_CATEGORY_VALUE = 'REFD' AND
CD.STATUS_VALUE = 'VALD' AND
CD.POSTED_DATE <= DR.ACCEPTED_TO_PAYROLL_DATE AND
DR.DISBURSEMENT_STATUS_VALUE <> 'CANL' AND
EXISTS
(
SELECT 1 FROM SGT_DISBURSEMENT_REQUEST SDR1
INNER JOIN SGT_DISBURSEMENT_DETAIL SDD1 ON SDD1.DISBURSEMENT_REQUEST_ID = SDR1.DISBURSEMENT_REQUEST_ID
WHERE SDR1.PERSON_ACCOUNT_ID = DR.PERSON_ACCOUNT_ID and SDD1.DETAIL_CATEGORY_VALUE = DD.DETAIL_CATEGORY_VALUE
GROUP BY SDR1.PERSON_ACCOUNT_ID
HAVING COUNT(*) = 1
)
GROUP BY
PA.PERSON_ID, PA.PERSON_ACCOUNT_ID, DR.DISBURSEMENT_REQUEST_ID, DD.PRE_TAX_AMOUNT, DD.POST_TAX_AMOUNT
For Performance improvement you can have the Filter Conditions in the Join Clause, instead of where clause. In this case each join will restrict the results to even lesser number of rows.
SELECT PA.PERSON_ID,
PA.PERSON_ACCOUNT_ID,
DR.DISBURSEMENT_REQUEST_ID,
SUM
(
ISNULL(CD.EE_PRE_TAX_AMT,0) +
ISNULL(CD.EE_ADDL_PRE_TAX_AMT,0)
) AS EE_PRE_TAX_CONTRIB,
DD.PRE_TAX_AMOUNT AS DISB_DTL_PRE_TAX_AMOUNT,
SUM
( ISNULL(CD.EE_POST_TAX_AMT,0) +
ISNULL(CD.EE_ADDL_POST_TAX_AMT,0)
) AS EE_POST_TAX_CONTRIB,
DD.POST_TAX_AMOUNT AS DISB_DTL_POST_TAX_AMOUNT
FROM SGT_DISBURSEMENT_REQUEST DR
INNER JOIN SGT_DISBURSEMENT_DETAIL DD ON DR.DISBURSEMENT_REQUEST_ID = DD.DISBURSEMENT_REQUEST_ID AND DR.REQUEST_CATEGORY_VALUE = 'REFD' AND
DD.DETAIL_CATEGORY_VALUE = 'REFD' AND DR.DISBURSEMENT_STATUS_VALUE <> 'CANL'
INNER JOIN SGT_PERSON_ACCOUNT PA ON PA.PERSON_ACCOUNT_ID = DR.PERSON_ACCOUNT_ID
INNER JOIN SGT_CONTRIB_DTL CD ON CD.PERSON_ACCOUNT_ID = PA.PERSON_ACCOUNT_ID AND CD.STATUS_VALUE = 'VALD' AND
CD.POSTED_DATE <= DR.ACCEPTED_TO_PAYROLL_DATE
WHERE EXISTS
(
SELECT 1 FROM SGT_DISBURSEMENT_REQUEST SDR1
INNER JOIN SGT_DISBURSEMENT_DETAIL SDD1 ON SDD1.DISBURSEMENT_REQUEST_ID = SDR1.DISBURSEMENT_REQUEST_ID
WHERE SDR1.PERSON_ACCOUNT_ID = DR.PERSON_ACCOUNT_ID and SDD1.DETAIL_CATEGORY_VALUE = DD.DETAIL_CATEGORY_VALUE
GROUP BY SDR1.PERSON_ACCOUNT_ID
HAVING COUNT(*) = 1
)
GROUP BY
PA.PERSON_ID, PA.PERSON_ACCOUNT_ID, DR.DISBURSEMENT_REQUEST_ID, DD.PRE_TAX_AMOUNT, DD.POST_TAX_AMOUNT
if you use count over it should give you the same result and be better for performance:
select * from (
SELECT PA.PERSON_ID,
PA.PERSON_ACCOUNT_ID,
DR.DISBURSEMENT_REQUEST_ID,
SUM
(
ISNULL(CD.EE_PRE_TAX_AMT,0) +
ISNULL(CD.EE_ADDL_PRE_TAX_AMT,0)
) AS EE_PRE_TAX_CONTRIB,
DD.PRE_TAX_AMOUNT AS DISB_DTL_PRE_TAX_AMOUNT,
SUM
( ISNULL(CD.EE_POST_TAX_AMT,0) +
ISNULL(CD.EE_ADDL_POST_TAX_AMT,0)
) AS EE_POST_TAX_CONTRIB,
DD.POST_TAX_AMOUNT AS DISB_DTL_POST_TAX_AMOUNT
,count(*) over(partition by PA.PERSON_ACCOUNT_ID ) as ct
FROM SGT_DISBURSEMENT_REQUEST DR
INNER JOIN SGT_DISBURSEMENT_DETAIL DD ON DR.DISBURSEMENT_REQUEST_ID = DD.DISBURSEMENT_REQUEST_ID
INNER JOIN SGT_PERSON_ACCOUNT PA ON PA.PERSON_ACCOUNT_ID = DR.PERSON_ACCOUNT_ID
INNER JOIN SGT_CONTRIB_DTL CD ON CD.PERSON_ACCOUNT_ID = PA.PERSON_ACCOUNT_ID
WHERE DR.REQUEST_CATEGORY_VALUE = 'REFD' AND
DD.DETAIL_CATEGORY_VALUE = 'REFD' AND
CD.STATUS_VALUE = 'VALD' AND
CD.POSTED_DATE <= DR.ACCEPTED_TO_PAYROLL_DATE AND
DR.DISBURSEMENT_STATUS_VALUE <> 'CANL'
GROUP BY
PA.PERSON_ID, PA.PERSON_ACCOUNT_ID, DR.DISBURSEMENT_REQUEST_ID, DD.PRE_TAX_AMOUNT, DD.PRE_TAX_AMOUNT, DD.POST_TAX_AMOUNT
) as x
where x.ct = 1
I would materialize this to a #temp
SELECT DR1.PERSON_ACCOUNT_ID, SDD1.DETAIL_CATEGORY_VALUE
FROM SGT_DISBURSEMENT_REQUEST SDR1
JOIN SGT_DISBURSEMENT_DETAIL SDD1
ON SDD1.DISBURSEMENT_REQUEST_ID = SDR1.DISBURSEMENT_REQUEST_ID
GROUP BY SDR1.PERSON_ACCOUNT_ID, SDD1.DETAIL_CATEGORY_VALUE
HAVING COUNT(*) = 1
join #temp
on #temp.PERSON_ACCOUNT_ID = DR.PERSON_ACCOUNT_ID
and #temp.DETAIL_CATEGORY_VALUE = DD.DETAIL_CATEGORY_VALUE

connot perform an aggregate function ... with GROUP BY

Hello i'm trying to write a query which consists to calculate the sum of 2 values, the second sum is result of multiplication between the first value and another. could someone help to solve this please ?? ( excuse me for my english, im frensh developer ) :
SELECT ISNULL(CONVERT(VARCHAR,CONVERT(date,MARE_DAT_CRE,103)),'Total') AS Dat
, SUM (MARE_CAUTIONNEMENT) AS HT
, SUM ( MARE_CAUTIONNEMENT * ( SELECT DISTINCT LCF_TAUXTVA
FROM F_LIGNECOMFOU
INNER JOIN F_AFFAIRES ON LCF_CODE_AFF = AF_CODE_AFFAIRE
INNER JOIN F_LOT ON LT_AFFAIRE = AF_CODE_AFFAIRE
INNER JOIN F_COMMANDEFOU ON CF_NUMERO = LCF_CF_NUMERO
INNER JOIN F_P_FOURNISSEUR ON CF_IDENT_FO = FOU_IDENT
WHERE AF_CODE_AFFAIRE = '15065-00' AND LT_IDENT = 500002200 AND FOU_IDENT = 500000838 ) ) FROM F_AVENANT_RETENUE INNER JOIN F_MARCHE_AVENANT ON MAAV_IDENT = MARE_MAAV_IDENT INNER JOIN F_MARCHE_TRAVAUX ON MATR_IDENT = MAAV_MATR_IDENT INNER JOIN F_AFFAIRES ON AF_CODE_AFFAIRE = MATR_AF_IDENT INNER JOIN F_LOT ON LT_AFFAIRE = AF_CODE_AFFAIRE INNER JOIN F_AVENANT_COTATION ON AVCO_IDENT = MARE_AVCO_IDENT WHERE AF_CODE_AFFAIRE = '15065-00' AND LT_IDENT = 500002200 AND MATR_FOU_IDENT = 500000838 AND MARE_CAUTIONNEMENT IS NOT NULL
GROUP BY MARE_DAT_CRE WITH ROLLUP
You could try sticking that sub select in your joins. Now you haven't used table alias so I'm not sure which tables contain the fields AF_CODE_AFFAIRE, LT_IDENT and MATR_FOU_IDENT so you'll have to add table aliases;
SELECT ISNULL(CONVERT(VARCHAR, CONVERT(DATE, MARE_DAT_CRE, 103)), 'Total') AS Dat
,SUM(MARE_CAUTIONNEMENT) AS HT
,SUM(MARE_CAUTIONNEMENT) * SUM(new.LCF_TAUXTVA)
FROM F_AVENANT_RETENUE
INNER JOIN F_MARCHE_AVENANT ON MAAV_IDENT = MARE_MAAV_IDENT
INNER JOIN F_MARCHE_TRAVAUX ON MATR_IDENT = MAAV_MATR_IDENT
INNER JOIN F_AFFAIRES ON AF_CODE_AFFAIRE = MATR_AF_IDENT
INNER JOIN F_LOT ON LT_AFFAIRE = AF_CODE_AFFAIRE
INNER JOIN F_AVENANT_COTATION ON AVCO_IDENT = MARE_AVCO_IDENT
LEFT JOIN (
SELECT DISTINCT LCF_TAUXTVA
FROM F_LIGNECOMFOU
INNER JOIN F_AFFAIRES ON LCF_CODE_AFF = AF_CODE_AFFAIRE
INNER JOIN F_LOT ON LT_AFFAIRE = AF_CODE_AFFAIRE
INNER JOIN F_COMMANDEFOU ON CF_NUMERO = LCF_CF_NUMERO
INNER JOIN F_P_FOURNISSEUR ON CF_IDENT_FO = FOU_IDENT
) new ON AF_CODE_AFFAIRE = new.AF_CODE_AFFAIRE
AND LT_IDENT = new.LT_IDENT
AND MATR_FOU_IDENT = new.MATR_FOU_IDENT
WHERE AF_CODE_AFFAIRE = '15065-00'
AND LT_IDENT = 500002200
AND MATR_FOU_IDENT = 500000838
AND MARE_CAUTIONNEMENT IS NOT NULL
GROUP BY ISNULL(CONVERT(VARCHAR, CONVERT(DATE, MARE_DAT_CRE, 103)), 'Total')
WITH ROLLUP

can we use order by after where clause in subquery?

I am trying to sort the record on milestone id coloumn but it is throwing error at order by in subquery giving error as "The ORDER BY clause is invalid in views, inline functions, derived tables, subqueries, and common table expressions, unless TOP or FOR XML is also specified."
CREATE PROCEDURE [dbo].[spGetALLStudyCodedtls]
(
#StudyCodeId VARCHAR(MAX)
)
AS
BEGIN
SELECT X.[IsActive]
--scd.[StudyCodeId]
,
X.[StudyCode],
X.[ProductName],
X.[TherapyName],
X.[Dosage],
X.[StudyType],
X.[Condition],
X.[CountryName],
X.[CRO],
X.[Design],
X.[DesignTag],
X.[RnD ProjManager],
X.[Project Manager],
X.[IPDFillingTimeline],
X.[Comments],
X.[MileStoneId],
X.[Milestone],
X.[Category],
X.[BaseLineDate],
X.[ActualDate]
FROM (
SELECT sc.IsActive
--scd.[StudyCodeId]
,
scd.[StudyCode],
pm.ProductName,
tm.TherapyName,
dm.Dosage,
stm.StudyType,
com.Condition,
cn.CountryName,
crm.CRO,
dsm.Design,
dtm.DesignTag,
ud.[user_name] AS 'RnD ProjManager',
udd.[user_name] AS 'Project Manager',
scd.[IPDFillingTimeline],
scd.[Remarks] AS 'Comments',
mm.MileStoneId,
mm.MileStoneName AS 'Milestone',
mm.Category AS 'Category',
sc.[BaseLineDate],
sc.[ActualDate]
FROM [PMS].[dbo].[StudyCodeDetails] scd
INNER JOIN [dbo].[StudyCodeToMileStone] sc ON scd.StudyCodeId = sc.StudyCodeId
INNER JOIN [dbo].[MileStoneMaster] mm ON sc.MileStoneId = mm.MileStoneId
INNER JOIN dbo.ProductMaster pm ON scd.ProductId = pm.ProductId
INNER JOIN dbo.TherapyMaster tm ON tm.TherapyId = scd.TherapyId
INNER JOIN dbo.DosageMaster dm ON dm.DosageId = scd.DosageId
INNER JOIN dbo.CountryMaster cn ON cn.CountryId = scd.CountryId
INNER JOIN dbo.[User_Dtls] ud ON ud.Pk_ID = scd.RnDProjManagerId
INNER JOIN dbo.[User_Dtls] udd ON udd.Pk_ID = scd.ProjectManagerId
INNER JOIN dbo.CroMaster crm ON crm.CroId = scd.CRO
INNER JOIN dbo.DesignMaster dsm ON dsm.DesignId = scd.DesignId
INNER JOIN dbo.DesignTagMaster dtm ON dtm.DesignTagId = scd.DesignTagId
INNER JOIN dbo.StudyTypeMaster stm ON stm.StudyTypeId = scd.StudyTypeId
INNER JOIN dbo.ConditionMaster com ON com.ConditionId = scd.Condition
WHERE scd.StudyCodeId IN (
SELECT CAST(Item AS INTEGER)
FROM [dbo].[SplitString](#StudyCodeId, ',')
)
AND mm.[AdditionalPayment] = 0
ORDER BY mm.MileStoneId
) AS X
GROUP BY X.[IsActive]
--scd.[StudyCodeId]
,
X.[StudyCode],
X.[ProductName],
X.[TherapyName],
X.[Dosage],
X.[StudyType],
X.[Condition],
X.[CountryName],
X.[CRO],
X.[Design],
X.[DesignTag],
X.[RnD ProjManager],
X.[Project Manager],
X.[IPDFillingTimeline],
X.[Comments],
X.[MileStoneId],
X.[Milestone],
X.[Category],
X.[BaseLineDate],
X.[ActualDate]
END
Please try this one:
CREATE PROCEDURE [dbo].[spGetALLStudyCodedtls]
(
#StudyCodeId VARCHAR(MAX)
)
AS
BEGIN
SELECT X.[IsActive]
--scd.[StudyCodeId]
,
X.[StudyCode],
X.[ProductName],
X.[TherapyName],
X.[Dosage],
X.[StudyType],
X.[Condition],
X.[CountryName],
X.[CRO],
X.[Design],
X.[DesignTag],
X.[RnD ProjManager],
X.[Project Manager],
X.[IPDFillingTimeline],
X.[Comments],
X.[MileStoneId],
X.[Milestone],
X.[Category],
X.[BaseLineDate],
X.[ActualDate]
FROM (
SELECT t1.IsActive,
t1.[StudyCode],
t2.ProductName,
t2.TherapyName,
t2.Dosage,
t2.StudyType,
t2.Condition,
t2.CountryName,
t2.CRO,
t2.Design,
t2.DesignTag,
t2.[user_name] AS 'RnD ProjManager',
t2.[user_name] AS 'Project Manager',
t1.[IPDFillingTimeline],
scd.[Remarks] AS 'Comments',
t2.MileStoneId,
t2.MileStoneName AS 'Milestone',
t2.Category AS 'Category',
t1.[BaseLineDate],
t1.[ActualDate]
FROM
(
SELECT sc.IsActive,
scd.[StudyCode],
scd.[IPDFillingTimeline],
scd.[Remarks] AS 'Comments',
sc.[BaseLineDate],
sc.[ActualDate],
sc.MileStoneId
FROM [PMS].[dbo].[StudyCodeDetails] scd
INNER JOIN [dbo].[StudyCodeToMileStone] sc
ON scd.StudyCodeId = sc.StudyCodeId
) AS t1
CROSS APPLY (
SELECT pm.ProductName,
tm.TherapyName,
dm.Dosage,
stm.StudyType,
com.Condition,
cn.CountryName,
crm.CRO,
dsm.Design,
dtm.DesignTag,
ud.[user_name] AS 'RnD ProjManager',
udd.[user_name] AS 'Project Manager',
mm.MileStoneId,
mm.MileStoneName AS 'Milestone',
mm.Category AS 'Category',
FROM [dbo].[MileStoneMaster] mm
INNER JOIN dbo.ProductMaster pm ON scd.ProductId = pm.ProductId
INNER JOIN dbo.TherapyMaster tm ON tm.TherapyId = scd.TherapyId
INNER JOIN dbo.DosageMaster dm ON dm.DosageId = scd.DosageId
INNER JOIN dbo.CountryMaster cn ON cn.CountryId = scd.CountryId
INNER JOIN dbo.[User_Dtls] ud ON ud.Pk_ID = scd.RnDProjManagerId
INNER JOIN dbo.[User_Dtls] udd ON udd.Pk_ID = scd.ProjectManagerId
INNER JOIN dbo.CroMaster crm ON crm.CroId = scd.CRO
INNER JOIN dbo.DesignMaster dsm ON dsm.DesignId = scd.DesignId
INNER JOIN dbo.DesignTagMaster dtm ON dtm.DesignTagId = scd.DesignTagId
INNER JOIN dbo.StudyTypeMaster stm ON stm.StudyTypeId = scd.StudyTypeId
INNER JOIN dbo.ConditionMaster com ON com.ConditionId = scd.Condition
WHERE scd.StudyCodeId IN (
SELECT CAST(Item AS INTEGER)
FROM [dbo].[SplitString](#StudyCodeId, ',')
)
AND mm.[AdditionalPayment] = 0
AND mm.MileStoneId = t1.MileStoneId
ORDER BY mm.MileStoneId
) AS t2
) AS X
GROUP BY X.[IsActive]
--scd.[StudyCodeId]
,
X.[StudyCode],
X.[ProductName],
X.[TherapyName],
X.[Dosage],
X.[StudyType],
X.[Condition],
X.[CountryName],
X.[CRO],
X.[Design],
X.[DesignTag],
X.[RnD ProjManager],
X.[Project Manager],
X.[IPDFillingTimeline],
X.[Comments],
X.[MileStoneId],
X.[Milestone],
X.[Category],
X.[BaseLineDate],
X.[ActualDate]
END