SQL-subquery workaround to join based on alias - sql

Attempted Subquery using alias
SELECT
*,
IQ.EndPart,
IQ.QtyToShip
FROM
parts p
INNER JOIN (
select
*,
(case when c.kitno is null then l.partno else c.partno end) as [EndPart],
(case when c.kitno is null then l.TotalQuantity else c.reqqty end) as [QtyToShip]
FROM
shipments s
INNER JOIN shipments_li l ON s.ShipmentNo = l.ShipmentNo
LEFT JOIN ProductConfiguration c ON l.PartNo = c.KitNo WHERE s.Status='N' and year(s.OrderDate)>2007
) IQ ON p.partno = IQ.EndPart
Looking for a way to join the parts table to my query below, using the part # which is aliased as EndPart. If there is another way to acheive the results of taking two columns and combining them instead of case and an alias that would be a great alternative as well. All my searches of other individuals quest to achieve the same have yielded the result you cannot perform a join based on alias because the results have not been determined at that point, recommending a subquery as a workaround. I'm just not sure how to acheive working results. The above query was what I attempted to get working. Any help appreciated. Thanks in advance.
Original Query
SELECT
*,
(case when c.kitno is null then l.partno else c.partno end) as [EndPart],
(case when c.kitno is null then l.TotalQuantity else c.reqqty end) as [QtyToShip]
FROM
shipments s
INNER JOIN shipments_li l ON s.ShipmentNo = l.ShipmentNo
LEFT JOIN ProductConfiguration c ON l.PartNo = c.KitNo
WHERE
s.Status='N'
and year(s.OrderDate)>2007
order by s.shipmentno

More proper way
--- CREATE TempTable
DECLARE #tblTemp AS TABLE (EndPart INT,
QtyToShip INT)
INSERT INTO #tblTemp (EndPart, QtyToShip)
SELECT
(CASE WHEN c.kitno IS NULL
THEN l.partno ELSE c.partno END) AS [EndPart],
(CASE WHEN c.kitno IS NULL
THEN l.TotalQuantity
ELSE c.reqqty END) AS [QtyToShip]
FROM dbo.Shipments s WITH(NOLOCK)
INNER JOIN shipments_li l WITH(NOLOCK) ON s.ShipmentNo = l.ShipmentNo
LEFT JOIN ProductConfiguration c WITH(NOLOCK) ON l.PartNo = c.KitNo
WHERE s.Status='N' AND YEAR(s.OrderDate)>2007
SELECT
p.*,
tmp.EndPart,
tmp.QtyToShip
FROM dbo.parts p WITH(NOLOCK)
INNER JOIN #tblTemp tmp ON p.partno = tmp.EndPart

Related

How to pass multiple values in parameter

In this stored procedure, I need to pass multiple parameter values in #GDNNO. Right now I can pass only a single value.
Please help me.
ALTER PROCEDURE dbo.xspSHEGONPrintQuery4
#GDNNO varchar(4000) = ''
AS
BEGIN
SELECT
a.ID, a.[To], a.FlowCode, a.TranNum, a.Status,
ART.ARTICLECODE, StockGDNID, DetailID, SubDocCode, ArticleID,
ColorCode, ColorName, SizeCode, SizeName,
DispatchedUnits * (CASE WHEN u.value IS NULL THEN FreezeStoringUOM ELSE u.value END) AS DispatchedUnits
FROM
xtstockgdn a (nolock)
JOIN
xtstockgdndetail b (nolock) ON a.id = b.stockgdnid
JOIN
XTARTICLE ART (nolock) ON ART.ID = B.ARTICLEID
LEFT JOIN
xtUOMConversion u (nolock) ON u.FromUOM = art.StoringUOM
AND u.ToUOM = art.consuom
WHERE
a.ID IN (#GDNNO)
AND FlowCode = 'POO_RET[E-]'
END
Since your query is only Select it can be change to TVF(table-value function). Change your Procedure to TVF
CREATE FUNCTION dbo.xspSHEGONPrintQuery4(
#GDNNO varchar(4000) = ''
)
RETURNS TABLE
AS
RETURN
SELECT
a.ID, a.[To], a.FlowCode, a.TranNum, a.Status,
ART.ARTICLECODE, StockGDNID, DetailID, SubDocCode, ArticleID,
ColorCode, ColorName, SizeCode, SizeName,
DispatchedUnits * (CASE WHEN u.value IS NULL THEN FreezeStoringUOM ELSE u.value END) AS DispatchedUnits
FROM
xtstockgdn a (nolock)
JOIN
xtstockgdndetail b (nolock) ON a.id = b.stockgdnid
JOIN
XTARTICLE ART (nolock) ON ART.ID = B.ARTICLEID
LEFT JOIN
xtUOMConversion u (nolock) ON u.FromUOM = art.StoringUOM
AND u.ToUOM = art.consuom
WHERE
a.ID IN (#GDNNO)
AND FlowCode = 'POO_RET[E-]'
END
Then use Cross apply to your TVF
Select a.GDNNO,b.* from yourtable a /*list of GDNNO Values */
Cross Apply dbo.xspSHEGONPrintQuery4(a.GDNNO) b
you can use Dynamic query as well

Remove duplicate address_id from sql data set

I need to get only distinct address_id in result no duplication. Here is my query.
SELECT DISTINCT address.address_id, address.address1, address.streetcity, state.stateabbrev, rtrim(ltrim(case when address.streetzipcode is not null and address.streetzipcode != 'NULL' then address.streetzipcode else '' end))+case when len(address.streetzipplus4)>0 then '-'+rtrim(ltrim(address.streetzipplus4)) else '' end as streetzipcode, address.homephone,
dbo.f_addressstudent (student.address_id) as Students,
dbo.f_addresspeople (student.address_id) as Adults,
case
when #classif_id IS NULL then 0
else
student.classif_id
end classif,
classifctn
FROM district WITH(NOLOCK)
JOIN dbo.building ON building.district_id = district.district_id
JOIN dbo.studbldg_bridge WITH(NOLOCK) ON studbldg_bridge.bldg_id=building.bldg_id
JOIN dbo.student WITH(NOLOCK) ON student.student_id = studbldg_bridge.student_id
JOIN classif with(nolock) on student.classif_id = classif.classif_id
LEFT JOIN dbo.address WITH(NOLOCK) ON student.address_id = address.address_id
LEFT JOIN dbo.state WITH(NOLOCK) ON address.streetstate_id = state.state_id
LEFT JOIN dbo.state AS mailstate WITH(NOLOCK) ON address.state_id = mailstate.state_id
WHERE district.district_id = (SELECT district_id FROM dbo.building WITH(NOLOCK) WHERE bldg_id = #bldg_id)
ORDER BY classif,Adults, Students
Here is result of query
Query result with error in data
I have tried to group by and use aggregate function with address_id but I also have non-aggregate columns so it didn't worked for me.
After that I also tried using OVER(partition by address.address_id) but it also didn't worked.
Any help will be appreciated in advance.
Thank you
**UPDATE on Business logic/Requirements **
I need to get unique addresses for parents of students. As parent can have two or more children living in same address, it causes duplication. I need to get only one child per parent in other words.
From your image of the results it looks like the classifctn column has more than 1 value so it is repeating your row by that. In order to get 1 distinct address_id and rest of the columns either remove it from your query or you can set a precedence that will only return 1 record per address_id
further please tag only the RDBMs you ware actually using. MySQL for example doesn't have window functions yet you tagged it yet referenced using OVER(partition.... which would not be possible in mysql
;WITH cte (
SELECT DISTINCT address.address_id, address.address1, address.streetcity, state.stateabbrev, rtrim(ltrim(case when address.streetzipcode is not null and address.streetzipcode != 'NULL' then address.streetzipcode else '' end))+case when len(address.streetzipplus4)>0 then '-'+rtrim(ltrim(address.streetzipplus4)) else '' end as streetzipcode, address.homephone,
dbo.f_addressstudent (student.address_id) as Students,
dbo.f_addresspeople (student.address_id) as Adults,
case
when #classif_id IS NULL then 0
else
student.classif_id
end classif,
classifctn,
ROW_NUMBER() OVER (PARTITION BY address.address_id ORDER BY HOW WILL YOU CHOOSE?) AS RowNum
FROM district WITH(NOLOCK)
JOIN dbo.building ON building.district_id = district.district_id
JOIN dbo.studbldg_bridge WITH(NOLOCK) ON studbldg_bridge.bldg_id=building.bldg_id
JOIN dbo.student WITH(NOLOCK) ON student.student_id = studbldg_bridge.student_id
JOIN classif with(nolock) on student.classif_id = classif.classif_id
LEFT JOIN dbo.address WITH(NOLOCK) ON student.address_id = address.address_id
LEFT JOIN dbo.state WITH(NOLOCK) ON address.streetstate_id = state.state_id
LEFT JOIN dbo.state AS mailstate WITH(NOLOCK) ON address.state_id = mailstate.state_id
WHERE district.district_id = (SELECT district_id FROM dbo.building WITH(NOLOCK) WHERE bldg_id = #bldg_id)
)
SELECT *
FROM
cte
WHERE
RowNum = 1
ORDER BY
classif
,Adults
,Students
Alternatively you could nest your select query. note though this solution is somewhat useless as it will only return 1 grade/classifctn when more than 1 exists in a household if you really don't care about the column then you should just remove it from your query.
Actually both your classifctn and classif columns will cause you multiple rows when more than 1 student is at the same address. here is a way to concatenate those values to a single row. You should spend some more time on your business case and defining it for us. But here is one example for you:
SELECT DISTINCT
address.address_id
,address.address1
,address.streetcity
,state.stateabbrev
,LTRIM(RTRIM(ISNULL(NULLIF(address.streetzipcode,'NULL'),'')))
+ CASE WHEN LEN(address.streetzipplus4) > 0 THEN '-' ELSE '' END
+ LTRIM(RTRIM(ISNULL(address.streetzipplus4,''))) AS streetzipcode
,address.homephone
,dbo.f_addressstudent (student.address_id) as Students
,dbo.f_addresspeople (student.address_id) as Adults
, case
when #classif_id IS NULL then 0
else student.classif_id
end classif
,STUFF(
(SELECT ',' + CAST(classif_id AS VARCHAR(100))
FROM
classif c
WHERE c.classif = student.classif
FOR XML PATH(''))
,1,1,'') AS classifs
,STUFF(
(SELECT ',' + CAST(classifctn AS VARCHAR(100))
FROM
classif c
WHERE c.classif = student.classif
FOR XML PATH(''))
,1,1,'') AS classifctns
FROM
district WITH(NOLOCK)
INNER JOIN dbo.building
ON building.district_id = district.district_id
AND building.bldg_id = #bldg_id
INNER JOIN dbo.student WITH(NOLOCK)
ON student.student_id = studbldg_bridge.student_id
INNER JOIN dbo.address WITH(NOLOCK)
ON student.address_id = address.address_id
LEFT JOIN dbo.state WITH(NOLOCK)
ON address.streetstate_id = state.state_id
Note I when ahead and changed the zip code logic to show you some use of ISNULL() and NULLIF() that are helpful in cases like that. I also removed 3 tables because 2 are not used and the third ends up being used in a subselect to concatenate the values. Also address table was changed to an INNER JOIN because if an address doesn't exist all of the other information becomes blank/useless....
INNER JOIN dbo.studbldg_bridge WITH(NOLOCK) ON studbldg_bridge.bldg_id=building.bldg_id
LEFT JOIN dbo.state AS mailstate WITH(NOLOCK) ON address.state_id = mailstate.state_id
INNER JOIN classif with(nolock) on student.classif_id = classif.classif_id

SQl Error : Each GROUP BY expression must contain at least one column that is not an outer reference [duplicate]

This question already has answers here:
Each GROUP BY expression must contain at least one column that is not an outer reference
(8 answers)
Closed 6 years ago.
I get this error
Each GROUP BY expression must contain at least one column that is not an outer reference
while running this query:
SELECT TOP 1
SUM(mla.total_current_attribute_value)
FROM
partstrack_machine_location_attributes mla (NOLOCK)
INNER JOIN
#tmpInstallParts_Temp installpartdetails ON mla.machine_sequence_id = installpartdetails.InstallKitToMachineSequenceId
AND (CASE WHEN mla.machine_side_id IS NULL THEN 1
WHEN mla.machine_side_id = installpartdetails.InstallKitToMachineSideId THEN 1 END
) = 1
INNER JOIN
partstrack_mes_attribute_mapping mam (NOLOCK) ON mla.mes_attribute = mam.mes_attribute_name
INNER JOIN
partstrack_attribute_type at (NOLOCK) ON mam.pt_attribute_id = at.pt_attribute_id
INNER JOIN
partstrack_ipp_mes_attributes ima(NOLOCK) ON at.pt_attribute_id = ima.pt_attribute_id
WHERE
mla.active_ind = 'Y' AND
ima.ipp_ID IN (SELECT ipp.ipp_id
FROM partstrack_individual_physical_part ipp
INNER JOIN #tmpInstallParts_Temp tmp ON (ipp.ipp_id = tmp.InstallingPartIPPId OR
(CASE WHEN tmp.InstallingPartIPKId = '-1' THEN 1 END) = 1
)
GROUP BY
ima.ipp_id
Can someone help me?
This is the text of the query from the first revision of the question.
In later revisions you removed the last closing bracket ) and the query became syntactically incorrect. You'd better check and fix the text of the question and format the text of the query, so it is readable.
SELECT TOP 1
SUM(mla.total_current_attribute_value)
FROM
partstrack_machine_location_attributes mla (NOLOCK)
INNER JOIN #tmpInstallParts_Temp installpartdetails
ON mla.machine_sequence_id = installpartdetails.InstallKitToMachineSequenceId
AND (CASE WHEN mla.machine_side_id IS NULL THEN 1
WHEN mla.machine_side_id = installpartdetails.InstallKitToMachineSideId THEN 1 END) = 1
INNER JOIN partstrack_mes_attribute_mapping mam (NOLOCK) ON mla.mes_attribute = mam.mes_attribute_name
INNER JOIN partstrack_attribute_type at (NOLOCK) ON mam.pt_attribute_id = at.pt_attribute_id
INNER JOIN partstrack_ipp_mes_attributes ima(NOLOCK) ON at.pt_attribute_id = ima.pt_attribute_id
WHERE
mla.active_ind = 'Y'
AND ima.ipp_ID IN
(
Select
ipp.ipp_id
FROM
partstrack_individual_physical_part ipp
INNER JOIN #tmpInstallParts_Temp tmp
ON (ipp.ipp_id = tmp.InstallingPartIPPId
OR (CASE WHEN tmp.InstallingPartIPKId = '-1' THEN 1 END) = 1)
GROUP BY
ima.ipp_id
)
With this formatting it is clear now that there is a subquery with GROUP BY.
Most likely it is just a typo: you meant to write GROUP BY ipp.ipp_id instead of GROUP BY ima.ipp_id.
If you really wanted to have the GROUP BY not in a subquery, but in the main SELECT, then you misplaced the closing bracket ) and the query should look like this:
SELECT TOP 1
SUM(mla.total_current_attribute_value)
FROM
partstrack_machine_location_attributes mla (NOLOCK)
INNER JOIN #tmpInstallParts_Temp installpartdetails
ON mla.machine_sequence_id = installpartdetails.InstallKitToMachineSequenceId
AND (CASE WHEN mla.machine_side_id IS NULL THEN 1
WHEN mla.machine_side_id = installpartdetails.InstallKitToMachineSideId THEN 1 END) = 1
INNER JOIN partstrack_mes_attribute_mapping mam (NOLOCK) ON mla.mes_attribute = mam.mes_attribute_name
INNER JOIN partstrack_attribute_type at (NOLOCK) ON mam.pt_attribute_id = at.pt_attribute_id
INNER JOIN partstrack_ipp_mes_attributes ima(NOLOCK) ON at.pt_attribute_id = ima.pt_attribute_id
WHERE
mla.active_ind = 'Y'
AND ima.ipp_ID IN
(
Select
ipp.ipp_id
FROM
partstrack_individual_physical_part ipp
INNER JOIN #tmpInstallParts_Temp tmp
ON (ipp.ipp_id = tmp.InstallingPartIPPId
OR (CASE WHEN tmp.InstallingPartIPKId = '-1' THEN 1 END) = 1)
)
GROUP BY
ima.ipp_id
In any case, proper formatting of the source code can really help.
Group By ima.ipp_id
should be applicable to outer query. Because of incorrect placement of '(' it was applying to inner query.
Now after correcting the query,it's working fine without any issues.
Final Query is :
SELECT TOP 1
SUM(mla.total_current_attribute_value)
FROM
partstrack_machine_location_attributes mla (NOLOCK)
INNER JOIN #tmpInstallParts_Temp installpartdetails
ON mla.machine_sequence_id = installpartdetails.InstallKitToMachineSequenceId
AND (CASE WHEN mla.machine_side_id IS NULL THEN 1
WHEN mla.machine_side_id = installpartdetails.InstallKitToMachineSideId THEN 1 END ) = 1
INNER JOIN partstrack_mes_attribute_mapping mam (NOLOCK) ON mla.mes_attribute = mam.mes_attribute_name
INNER JOIN partstrack_attribute_type at (NOLOCK) ON mam.pt_attribute_id = at.pt_attribute_id
INNER JOIN partstrack_ipp_mes_attributes ima(NOLOCK) ON at.pt_attribute_id = ima.pt_attribute_id
WHERE
mla.active_ind = 'Y'
AND ima.ipp_ID IN
(
Select
ipp.ipp_id
FROM
partstrack_individual_physical_part ipp
INNER JOIN #tmpInstallParts_Temp tmp
ON (ipp.ipp_id = tmp.InstallingPartIPPId
OR (CASE WHEN tmp.InstallingPartIPKId = '-1' THEN 1 END ) =1)
)
GROUP BY ima.ipp_id
Thank you all.

Selecting columns based on a case SQL

I'm wondering how I can return specific results depending on my first selected statement. Basically I have two IDs. CustBillToID and CustShipToID. If CustShipToID is not null I want to select that and all the records that are joined to it. If it is null default to the CustBillToID and all the results that are joined to that.
Here is my SQL that obviously doesn't work. I should mention I tried to do a sub query in the conditional, but since it returns multiple results it won't work. I am using SQL Server 2012.
SELECT CASE WHEN cp.CustShipToID IS NOT NULL
THEN
cy.CustDesc,
cy.Address1,
cy.Address2,
cy.City,
cy.State,
cy.ZIP,
cy.Phone
ELSE
c.CustDesc,
c.Address1,
c.Address2,
c.City,
c.State,
c.ZIP,
c.Phone
END
LoadID,
cp.CustPOID,
cp.POBillToRef,
cp.POShipToRef,
cp.CustBillToID,
cp.CustShipToID,
cp.ArrivalDate,
cp.LoadDate,
cp.StopNum,
cp.ConfNum,
cp.EVNum,
cp.ApptNum,
ld.CarrId,
ld.Temperature,
cr.CarrDesc
FROM [Sales].[dbo].[CustPO] AS cp
LEFT OUTER JOIN Load AS ld
ON cp.LoadID = ld.LoadID
LEFT OUTER JOIN Carrier AS cr
ON ld.CarrId = cr.CarrId
LEFT OUTER JOIN Customer AS c
ON c.CustId = cp.CustBillToID
WHERE CustPOID=5213
Any ideas?
Also my current SQL is below, I do a conditional to determine if it's set. I'd rather do it in SQL if possible.
SELECT cp.LoadID,
cp.CustPOID,
cp.POBillToRef,
cp.POShipToRef,
cp.CustBillToID,
cp.CustShipToID,
cp.ArrivalDate,
cp.LoadDate,
cp.StopNum,
cp.ConfNum,
cp.EVNum,
cp.ApptNum,
ld.CarrId,
ld.Temperature,
cr.CarrDesc,
c.CustDesc as CustBillToDesc,
c.Address1 as CustBillAddress1,
c.Address2 as CustBillAddress2,
c.City as CustBillCity,
c.State as CustBillState,
c.ZIP as CustBillZIP,
c.Phone as CustBillPhone,
cy.CustDesc as CustShipToDesc,
cy.Address1 as CustShipAddress1,
cy.Address2 as CustShipAddress2,
cy.City as CustShipCity,
cy.State as CustShipState,
cy.ZIP as CustShipZIP,
cy.Phone as CustShipPhone
FROM [Sales].[dbo].[CustPO] as cp
left outer join Load as ld
on cp.LoadID = ld.LoadID
left outer join Carrier as cr
on ld.CarrId = cr.CarrId
left outer join Customer as c
on c.CustId = cp.CustBillToID
left outer join Customer as cy
on cy.CustId = cp.CustShipToID
WHERE CustPOID=?
You need a separate case for each column:
SELECT (CASE WHEN cp.CustShipToID IS NOT NULL THEN cy.CustDesc ELSE c.CustDesc END) as CustDesc,
(CASE WHEN cp.CustShipToID IS NOT NULL THEN cy.Address1 ELSE c.Address1 END) as Address1,
(CASE WHEN cp.CustShipToID IS NOT NULL THEN cy.Address2 ELSE c.Address2 END) as Address2,
(CASE WHEN cp.CustShipToID IS NOT NULL THEN cy.City ELSE c.City END) as City,
(CASE WHEN cp.CustShipToID IS NOT NULL THEN cy.State ELSE c.State END) as State,
(CASE WHEN cp.CustShipToID IS NOT NULL THEN cy.ZIP ELSE c.ZIP END) as ZIP,
(CASE WHEN cp.CustShipToID IS NOT NULL THEN cy.Phone ELSE c.Phone END) as Phone,
. . .
For this, you basically want to build a string that is your SQL and then execute the string...look # the answer to this one ::
SQL conditional SELECT
Did you try coalesce(CustShipToID,CustBillToID ) ?
...
FROM [Sales].[dbo].[CustPO] as cp
left outer join Load as ld
on cp.LoadID = ld.LoadID
left outer join Carrier as cr
on ld.CarrId = cr.CarrId
inner join Customer as c
on c.CustId = coalesce(cp.CustShipToID,cp.CustBillToID )
...

Query for logistic regression, multiple where exists

A logistic regression is a composed of a uniquely identifying number, followed by multiple binary variables (always 1 or 0) based on whether or not a person meets certain criteria. Below I have a query that lists several of these binary conditions. With only four such criteria the query takes a little longer to run than what I would think. Is there a more efficient approach than below? Note. tblicd is a large table lookup table with text representations of 15k+ rows. The query makes no real sense, just a proof of concept. I have the proper indexes on my composite keys.
select patient.patientid
,case when exists
(
select c.patientid from tblclaims as c
inner join patient as p on p.patientid=c.patientid
and c.admissiondate = p.admissiondate
and c.dischargedate = p.dischargedate
where patient.patientid = p.patientid
group by c.patientid
having count(*) > 1000
)
then '1' else '0'
end as moreThan1000
,case when exists
(
select c.patientid from tblclaims as c
inner join patient as p on p.patientid=c.patientid
and c.admissiondate = p.admissiondate
and c.dischargedate = p.dischargedate
where patient.patientid = p.patientid
group by c.patientid
having count(*) > 1500
)
then '1' else '0'
end as moreThan1500
,case when exists
(
select distinct picd.patientid from patienticd as picd
inner join patient as p on p.patientid= picd.patientid
and picd.admissiondate = p.admissiondate
and picd.dischargedate = p.dischargedate
inner join tblicd as t on t.icd_id = picd.icd_id
where t.descrip like '%diabetes%' and patient.patientid = picd.patientid
)
then '1' else '0'
end as diabetes
,case when exists
(
select r.patientid, count(*) from patient as r
where r.patientid = patient.patientid
group by r.patientid
having count(*) >1
)
then '1' else '0'
end
from patient
order by moreThan1000 desc
I would start by using subqueries in the from clause:
select q.patientid, moreThan1000, moreThan1500,
(case when d.patientid is not null then 1 else 0 end),
(case when pc.patientid is not null then 1 else 0 end)
from patient p left outer join
(select c.patientid,
(case when count(*) > 1000 then 1 else 0 end) as moreThan1000,
(case when count(*) > 1500 then 1 else 0 end) as moreThan1500
from tblclaims as c inner join
patient as p
on p.patientid=c.patientid and
c.admissiondate = p.admissiondate and
c.dischargedate = p.dischargedate
group by c.patientid
) q
on p.patientid = q.patientid left outer join
(select distinct picd.patientid
from patienticd as picd inner join
patient as p
on p.patientid= picd.patientid and
picd.admissiondate = p.admissiondate and
picd.dischargedate = p.dischargedate inner join
tblicd as t
on t.icd_id = picd.icd_id
where t.descrip like '%diabetes%'
) d
on p.patientid = d.patientid left outer join
(select r.patientid, count(*) as cnt
from patient as r
group by r.patientid
having count(*) >1
) pc
on p.patientid = pc.patientid
order by 2 desc
You can then probably simplify these subqueries more by combining them (for instance "p" and "pc" on the outer query can be combined into one). However, without the correlated subqueries, SQL Server should find it easier to optimize the queries.
Example of left joins as requested...
SELECT
patientid,
ISNULL(CondA.ConditionA,0) as IsConditionA,
ISNULL(CondB.ConditionB,0) as IsConditionB,
....
FROM
patient
LEFT JOIN
(SELECT DISTINCT patientid, 1 as ConditionA from ... where ... ) CondA
ON patient.patientid = CondA.patientID
LEFT JOIN
(SELECT DISTINCT patientid, 1 as ConditionB from ... where ... ) CondB
ON patient.patientid = CondB.patientID
If your Condition queries only return a maximum one row, you can simplify them down to
(SELECT patientid, 1 as ConditionA from ... where ... ) CondA