Subquery in from clause, Invalid Identifier in Where clause - sql

select * from iiasa_inventory.inv_device d
join iiasa_inventory.inv_type ty on d.type_id = ty.id
join iiasa_inventory.inv_category c on ty.category_id = c.id
join iiasa_inventory.inv_device_2_barcode b on b.device_id = d.id
join iiasa_inventory.inv_barcodes bc on b.barcode_id = bc.id
join iiasa_inventory.inv_status s on d.status = s.id
join iiasa_inventory.inv_brand br on ty.brand_id = br.id
left join iiasa_inventory.inv_supplier su on su.id = d.supplier_id
left join iiasa_inventory.inv_supplier sup on sup.id = d.maintenance_with
left join (select distinct device_id from
iiasa_inventory.inv_device_2_persons_cc) dp
on dp.device_id = d.id
where dp.active = 1
I am trying to select my data but the where-clause says that "dp.active" is an INVALID Identifier. This is probably because the table dp is in the subquery. I have tried to give it an alias name and some other things I found while browsing stackoverflow, but I cant seem to find a solution. Any idea?
This is Oracle PL/SQL.

Put the check for active = 1 in the subquery as shown below.
select * from iiasa_inventory.inv_device d
join iiasa_inventory.inv_type ty on d.type_id = ty.id
join iiasa_inventory.inv_category c on ty.category_id = c.id
join iiasa_inventory.inv_device_2_barcode b on b.device_id = d.id
join iiasa_inventory.inv_barcodes bc on b.barcode_id = bc.id
join iiasa_inventory.inv_status s on d.status = s.id
join iiasa_inventory.inv_brand br on ty.brand_id = br.id
left join iiasa_inventory.inv_supplier su on su.id = d.supplier_id
left join iiasa_inventory.inv_supplier sup on sup.id = d.maintenance_with
left join (select distinct device_id from iiasa_inventory.inv_device_2_persons_cc where active = 1) dp on dp.device_id = d.id

That is because you are not selecting active column in dp.
select * from iiasa_inventory.inv_device d
join iiasa_inventory.inv_type ty on d.type_id = ty.id
join iiasa_inventory.inv_category c on ty.category_id = c.id
join iiasa_inventory.inv_device_2_barcode b on b.device_id = d.id
join iiasa_inventory.inv_barcodes bc on b.barcode_id = bc.id
join iiasa_inventory.inv_status s on d.status = s.id
join iiasa_inventory.inv_brand br on ty.brand_id = br.id
left join iiasa_inventory.inv_supplier su on su.id = d.supplier_id
left join iiasa_inventory.inv_supplier sup on sup.id = d.maintenance_with
left join (select distinct device_id,active from iiasa_inventory.inv_device_2_persons_cc) dp on dp.device_id = d.id
where dp.active = 1
OR you can just filter from the subquery itself. Like:
left join (select distinct device_id
from iiasa_inventory.inv_device_2_persons_cc
where active=1) dp on dp.device_id = d.id

Related

SQL query doesn't work in my JOIN exercises

I am using SQL query but query resulted 12 lines, needs to be 3 lines; I can't figure it out.
Not working query:
SELECT g.*
,c.TxtFobFiyati
,C.TxtTalepETeslimTarihi
,c.TslParaBirimi
,c.TxtFiyat
,C.TslDepoKodu
,c.TslOlcuBirimi AS 'Olcu'
,j.TxtAmbalajDara
,j.TxtPaletDara
,g.TxtAdet AS 'ambalajAdet'
,g.TxtPaletSayisi AS 'paletSayisi'
,j.TxtAmbalajAdi
,J.TxtAmbalajNetKG
,j.TxtBoxGrossWeight
,C.TxtAciklama AS 'KalemAciklama'
,G.TxtAciklama AS 'KalemAciklama2'
,g.TxtPaletUstu AS 'PaletUstu'
,g.TxtPaletSayisi AS 'PaletSayisi'
,c.TxtUrunAdiEng AS 'UrunAdi_Ingilizce'
,C.TxtFobFiyati AS 'FobFiyati'
,j.TslPaletTipi AS 'PaletTipi'
,j.TxtPaletDara AS 'PaletDara'
FROM E_KT_SAS_Form A
LEFT JOIN E_KT_SAS_Form_DtyUrunler2 B
ON A.ID = B.FORMID
LEFT JOIN E_KT_SAS_FrmSipUrunEkle C
ON B.DOCUMENTID = C.ID
LEFT JOIN E_KT_SAS_Form_DtyTeyitEdilen2 D
ON A.ID = D.FORMID
LEFT JOIN E_KT_SAS_FrmUretimTarihiEkle E
ON D.DOCUMENTID = E.ID
AND E.TslUrun = C.TslUrunKodu
LEFT JOIN E_KT_SAS_Form_DtySevkiyatlar F
ON A.ID = F.FORMID
LEFT JOIN E_KT_SAS_FrmSevkiyatEkle G
ON F.DOCUMENTID = G.ID
LEFT JOIN E_KT_SAS_FrmSipUrunEkle_DtyAmbalajlama H
ON C.ID = H.FORMID
LEFT JOIN E_KT_SAS_FrmUrunAmbalajlama J
ON H.DOCUMENTID = J.ID
WHERE E.TslOnay_TEXT = 'Evet'
AND C.TslUrunKodu = G.TslUrun
AND A.ID = 11682
Not working result
Correct result table
Step1) Start count with the driver table i.e. the one you have alias as 'A'. Check the count if you get 3. Continue.
Repeat step 1 with each new join and see where your count blows up to 12. That is your troubling join. Comment it out if possible and continue with joins. If you cannot do successive joins then find best solution to bring count back down to 3.
If your sure of your where clause great; else start without it too. If count is more than 3. Pop it back in.
select count(1)
FROM E_KT_SAS_Form A
LEFT JOIN E_KT_SAS_Form_DtyUrunler2 B ON A.ID = B.FORMID
LEFT JOIN E_KT_SAS_FrmSipUrunEkle C ON B.DOCUMENTID = C.ID
LEFT JOIN E_KT_SAS_Form_DtyTeyitEdilen2 D ON A.ID = D.FORMID
LEFT JOIN E_KT_SAS_FrmUretimTarihiEkle E ON D.DOCUMENTID = E.ID
AND E.TslUrun = C.TslUrunKodu
LEFT JOIN E_KT_SAS_Form_DtySevkiyatlar F ON A.ID = F.FORMID
LEFT JOIN E_KT_SAS_FrmSevkiyatEkle G ON F.DOCUMENTID = G.ID
LEFT JOIN E_KT_SAS_FrmSipUrunEkle_DtyAmbalajlama H ON C.ID = H.FORMID
LEFT JOIN E_KT_SAS_FrmUrunAmbalajlama J ON H.DOCUMENTID = J.ID
WHERE E.TslOnay_TEXT = 'Evet' AND C.TslUrunKodu = G.TslUrun AND A.ID = 11682

How can I use the group by Clause in a subquery

I just need to select one more field in my query that is the date... but it's a subquery and i'm using a count field... and because of it i need to use the GROUP BY Clause... But i can't group by my subquery and the query is returning errors...
SELECT
X.NROF,
Z.NMGUERFORN,
C.CDCOMPRADO,
C.CDCOORDENA,
E.CDFUP,
count(*) AS ocorrencias
--(select TOP 1 DTPROGENTR from CMPENL0 C (NOLOCK) where X.NRPEDICOMP = C.NRPEDICOMP AND X.NRITEMPECO = C.NRITEMPECO) AS DTPROGENTR
FROM CMPCIL0 X (NOLOCK)
inner join CMPCCL0 Y (NOLOCK) on X.NRPEDICOMP = Y.NRPEDICOMP
inner join CMFRNL0 Z (NOLOCK) on Y.CDFORNECED1 = Z.CDFORNECED1
inner join CMSCPL0 M (NOLOCK) on X.NRSOLICOMP = M.NRSOLICOMP AND X.NRITEMSC = M.NRITEMSC
inner join CMPENL0 N (NOLOCK) on X.NRPEDICOMP = N.NRPEDICOMP AND X.NRITEMPECO = N.NRITEMPECO
inner join CMMATL0 A (NOLOCK) on X.CDMATERIAL = A.CDMATERIAL
inner join cmcomL0 c (NOLOCK) on c.cdcomprado = y.cdcomprado
LEFT JOIN AMCSPL0 D (NOLOCK) ON D.SCPE_NRSOLICOMP = X.NRSOLICOMP AND D.SCPE_NRITEMSC=X.NRITEMSC
LEFT JOIN CMFUPL0 E (NOLOCK) ON E.CDFORNECED1 = Z.CDFORNECED1
LEFT JOIN CMPFIL0 H ON Z.CDFORNECED1 = H.CDFORNECED1 AND X.NRIDENTIFI = H.NRIDENTIFI and H.DTVALIDADE > Y.DTEFETPECO
LEFT JOIN CMPENL0 F ON (X.NRPEDICOMP = F.NRPEDICOMP AND X.NRITEMPECO = F.NRITEMPECO)
WHERE X.CDSTATUS = 'P' and X.NROF <> 0
group by X.NROF,Z.NMGUERFORN,C.CDCOMPRADO,C.CDCOORDENA,E.CDFUP--,DTPROGENTR
order by 6 desc
The commented parts are the code im trying to include to select the field, but it is giving me errors..
The problem is that you use aliases in your where clause of select sub-query. Aliases cannot be referenced on the same level in the query. You should use full qualified names and the sub-query should look something like that:
(select TOP 1 DTPROGENTR from CMPENL0 C (NOLOCK) where X.NRPEDICOMP = CMPENL0.NRPEDICOMP AND X.NRITEMPECO = CMPENL0.NRITEMPECO) AS DTPROGENTR
If your sql-server supports common table expressions you can try that:
;WITH cte AS
(
SELECT ROW_NUMBER() OVER(PARTITION BY NRPEDICOMP, NRITEMPECO ORDER BY NRPEDICOMP) row_num
,DTPROGENTR
,NRPEDICOMP
,NRITEMPECO
FROM CMPENL0 (NOLOCK)
)
SELECT
X.NROF,
Z.NMGUERFORN,
C.CDCOMPRADO,
C.CDCOORDENA,
E.CDFUP,
count(*) AS ocorrencias
cte.DTPROGENTR
FROM CMPCIL0 X (NOLOCK)
inner join CMPCCL0 Y (NOLOCK) on X.NRPEDICOMP = Y.NRPEDICOMP
inner join CMFRNL0 Z (NOLOCK) on Y.CDFORNECED1 = Z.CDFORNECED1
inner join CMSCPL0 M (NOLOCK) on X.NRSOLICOMP = M.NRSOLICOMP AND X.NRITEMSC = M.NRITEMSC
inner join CMPENL0 N (NOLOCK) on X.NRPEDICOMP = N.NRPEDICOMP AND X.NRITEMPECO = N.NRITEMPECO
inner join CMMATL0 A (NOLOCK) on X.CDMATERIAL = A.CDMATERIAL
inner join cmcomL0 c (NOLOCK) on c.cdcomprado = y.cdcomprado
LEFT JOIN AMCSPL0 D (NOLOCK) ON D.SCPE_NRSOLICOMP = X.NRSOLICOMP AND D.SCPE_NRITEMSC=X.NRITEMSC
LEFT JOIN CMFUPL0 E (NOLOCK) ON E.CDFORNECED1 = Z.CDFORNECED1
LEFT JOIN CMPFIL0 H ON Z.CDFORNECED1 = H.CDFORNECED1 AND X.NRIDENTIFI = H.NRIDENTIFI and H.DTVALIDADE > Y.DTEFETPECO
LEFT JOIN CMPENL0 F ON X.NRPEDICOMP = F.NRPEDICOMP AND X.NRITEMPECO = F.NRITEMPECO
LEFT JOIN cte ON X.NRPEDICOMP = cte.NRPEDICOMP AND X.NRITEMPECO = cte.NRITEMPECO AND cte.row_num = 1
WHERE X.CDSTATUS = 'P' and X.NROF <> 0
group by X.NROF,Z.NMGUERFORN,C.CDCOMPRADO,C.CDCOORDENA,E.CDFUP, cte.DTPROGENTR
order by 6 desc

MSSQL How do I get average of four records from different tables?

I have four tables and I need to find the average of each score for a particular id. I do not need the ENTIRE Column average, but the average of each record with the same id in each table.
I have tried this:
SELECT DISTINCT M.system_id, S.name, SUM(A.Score + WAL.score + F.score + WIN.score) / 4
AS avgScore
FROM dbo.T3_MovementSystemJoin AS M
INNER JOIN dbo.T3_systems AS S ON M.system_id = S.id
INNER JOIN T3_ApplicationSystemJoin AS A ON A.Application_id = #application_id
INNER JOIN T3_WallTypeSystemJoin AS WAL ON WAL.wall_id = #wall_id
INNER JOIN T3_FenestrationSystemJoin AS F ON F.fenestration_id = #fen_id
INNER JOIN T3_WindowOrientation_System AS WIN ON WIN.window_id = #window_id
INNER JOIN T3_ConstructionSystemJoin AS C ON C.contruction_id = #construction_id
INNER JOIN T3_JointDepthSystemJoin AS J ON J.JointDepth_id = #JointDepth_id
INNER JOIN T3_JointGapSystemJoin AS JG ON JG.JointGap_id = #JointGap_id
WHERE (M.movement_id = #movement_id)
GROUP BY M.System_id, S.name
:
Thanks for your help!
No Sum needed (and no grouping too)
SELECT DISTINCT M.system_id, S.name, (IsNull(A.Score, 0) + IsNull(WAL.score, 0) + IsNull(F.score, 0) + IsNull(WIN.score, 0)) /4
as avgscore
FROM dbo.T3_MovementSystemJoin AS M
INNER JOIN dbo.T3_systems AS S ON M.system_id = S.id
INNER JOIN T3_ApplicationSystemJoin AS A ON A.Application_id = #application_id
INNER JOIN T3_WallTypeSystemJoin AS WAL ON WAL.wall_id = #wall_id
INNER JOIN T3_FenestrationSystemJoin AS F ON F.fenestration_id = #fen_id
INNER JOIN T3_WindowOrientation_System AS WIN ON WIN.window_id = #window_id
INNER JOIN T3_ConstructionSystemJoin AS C ON C.contruction_id = #construction_id
INNER JOIN T3_JointDepthSystemJoin AS J ON J.JointDepth_id = #JointDepth_id
INNER JOIN T3_JointGapSystemJoin AS JG ON JG.JointGap_id = #JointGap_id
WHERE (M.movement_id = #movement_id)
SELECT DISTINCT M.system_id
,S.name
,(ISNULL(A.Score,0) + ISNULL(WAL.score,0) + ISNULL(F.score,0) + ISNULL(WIN.score,0)) /4 as 'AvgScore'
FROM dbo.T3_MovementSystemJoin AS M
INNER JOIN dbo.T3_systems AS S ON M.system_id = S.id
INNER JOIN T3_ApplicationSystemJoin AS A ON A.Application_id = #application_id
INNER JOIN T3_WallTypeSystemJoin AS WAL ON WAL.wall_id = #wall_id
INNER JOIN T3_FenestrationSystemJoin AS F ON F.fenestration_id = #fen_id
INNER JOIN T3_WindowOrientation_System AS WIN ON WIN.window_id = #window_id
INNER JOIN T3_ConstructionSystemJoin AS C ON C.contruction_id = #construction_id
INNER JOIN T3_JointDepthSystemJoin AS J ON J.JointDepth_id = #JointDepth_id
INNER JOIN T3_JointGapSystemJoin AS JG ON JG.JointGap_id = #JointGap_id
WHERE (M.movement_id = #movement_id)
If you don't want NULL values to become zeros and included in the average:
SELECT DISTINCT M.system_id, S.name, X.avgScore
FROM dbo.T3_MovementSystemJoin AS M
INNER JOIN dbo.T3_systems AS S ON M.system_id = S.id
INNER JOIN T3_ApplicationSystemJoin AS A ON A.Application_id = #application_id
INNER JOIN T3_WallTypeSystemJoin AS WAL ON WAL.wall_id = #wall_id
INNER JOIN T3_FenestrationSystemJoin AS F ON F.fenestration_id = #fen_id
INNER JOIN T3_WindowOrientation_System AS WIN ON WIN.window_id = #window_id
INNER JOIN T3_ConstructionSystemJoin AS C ON C.contruction_id = #construction_id
INNER JOIN T3_JointDepthSystemJoin AS J ON J.JointDepth_id = #JointDepth_id
INNER JOIN T3_JointGapSystemJoin AS JG ON JG.JointGap_id = #JointGap_id
CROSS APPLY ( SELECT AVG(s) FROM (VALUES (A.Score),(WAL.score),(F.score),(WIN.score) ) scores(s) ) X(avgScore)
WHERE (M.movement_id = #movement_id)
GROUP BY M.System_id, S.name

Error: Cannot use an aggregate or a subquery in an expression used for the group by list

I'm getting this error: Cannot use an aggregate or a subquery in an expression used for the group by list of a GROUP BY clause.
I searched on internet, but i don't know how to apply the correction in my case. I found different types of query only.
I'm trying to get a Count result in a field (line 5), but when I add the Count query i'm getting this error.
I'm using SQL SERVER 2008 R2.
When I remove the Count from SELECT and GROUP BY the query run correctly.
SELECT TF.COD_FORNECEDOR AS 'Cód. Fornec.',
TF.NOM_FANTASIA AS 'Fornecedor',
DM.COD_CONTRATO_RELACIONADO AS 'CONTRATO',
UA2.NOM_USUARIO AS 'NOM_USUARIO_COMPRADOR',
(SELECT COUNT(COD_CONTRATO_RELACIONADO) FROM TB_DEMANDA D INNER JOIN TB_PROCESSO P ON D.COD_CONTRATO_RELACIONADO = P.NUM_CONTRATO WHERE D.COD_CONTRATO_RELACIONADO = DM.COD_CONTRATO_RELACIONADO) AS 'NUM_ADITIVO',
0 AS 'Qtd. Aditivo',
SUM(DM.VAL_TOTAL_ORCADO) AS 'Valor Inicial',
SUM(TP.VAL_CONTRATADO) AS 'Valor Final',
((SUM(TP.VAL_CONTRATADO) / SUM(DM.VAL_TOTAL_ORCADO)) -1) * 100 AS 'Var. %'
FROM TB_FORNECEDOR TF
LEFT JOIN TB_DEMANDA DM ON DM.COD_FORNECEDOR = TF.COD_FORNECEDOR
LEFT JOIN TB_PROCESSO TP ON DM.COD_DEMANDA = TP.COD_DEMANDA
LEFT JOIN TB_PROCESSO_FORNECEDOR PF ON PF.COD_PROCESSO = TP.COD_PROCESSO
LEFT JOIN USUARIO UA ON UA.NUM_USUARIO = DM.NUM_USUARIO_COMPRADOR
LEFT JOIN USUARIO UA2 ON UA2.NUM_USUARIO = DM.NUM_USUARIO_COMPRADOR
LEFT JOIN TB_STATUS_DEMANDA_DATA SD ON SD.COD_DEMANDA = DM.COD_DEMANDA
LEFT JOIN TB_BASELINE BA ON BA.COD_PROCESSO = TP.COD_PROCESSO
LEFT JOIN TB_BASELINE_TAREFAS BT ON BT.COD_BASELINE = BA.COD_BASELINE AND BT.COD_PROCESSO = BA.COD_PROCESSO
LEFT JOIN TB_STATUS_PROCESSO SP ON SP.COD_STATUS = SD.COD_STATUS
LEFT JOIN TB_MEDIO_STATUS MS ON MS.COD_MEDIO_STATUS = SP.COD_MEDIO_STATUS
left JOIN #TB_PROCESSO TT ON TT.COD_PROCESSO = TP.COD_PROCESSO
GROUP BY
TF.COD_FORNECEDOR,
TF.NOM_FANTASIA,
DM.COD_CONTRATO_RELACIONADO,
UA2.NOM_USUARIO,
(SELECT COUNT(COD_CONTRATO_RELACIONADO) FROM TB_DEMANDA D INNER JOIN TB_PROCESSO P ON D.COD_CONTRATO_RELACIONADO = P.NUM_CONTRATO WHERE D.COD_CONTRATO_RELACIONADO = DM.COD_CONTRATO_RELACIONADO)
ORDER BY TF.NOM_FANTASIA
Try this:
SELECT TF.COD_FORNECEDOR AS 'Cód. Fornec.',
TF.NOM_FANTASIA AS 'Fornecedor',
DM.COD_CONTRATO_RELACIONADO AS 'CONTRATO',
UA2.NOM_USUARIO AS 'NOM_USUARIO_COMPRADOR',
sq.cnt AS 'NUM_ADITIVO',
0 AS 'Qtd. Aditivo',
SUM(DM.VAL_TOTAL_ORCADO) AS 'Valor Inicial',
SUM(TP.VAL_CONTRATADO) AS 'Valor Final',
((SUM(TP.VAL_CONTRATADO) / SUM(DM.VAL_TOTAL_ORCADO)) -1) * 100 AS 'Var. %'
FROM TB_FORNECEDOR TF
LEFT JOIN TB_DEMANDA DM ON DM.COD_FORNECEDOR = TF.COD_FORNECEDOR
LEFT JOIN TB_PROCESSO TP ON DM.COD_DEMANDA = TP.COD_DEMANDA
LEFT JOIN TB_PROCESSO_FORNECEDOR PF ON PF.COD_PROCESSO = TP.COD_PROCESSO
LEFT JOIN USUARIO UA ON UA.NUM_USUARIO = DM.NUM_USUARIO_COMPRADOR
LEFT JOIN USUARIO UA2 ON UA2.NUM_USUARIO = DM.NUM_USUARIO_COMPRADOR
LEFT JOIN TB_STATUS_DEMANDA_DATA SD ON SD.COD_DEMANDA = DM.COD_DEMANDA
LEFT JOIN TB_BASELINE BA ON BA.COD_PROCESSO = TP.COD_PROCESSO
LEFT JOIN TB_BASELINE_TAREFAS BT ON BT.COD_BASELINE = BA.COD_BASELINE AND BT.COD_PROCESSO = BA.COD_PROCESSO
LEFT JOIN TB_STATUS_PROCESSO SP ON SP.COD_STATUS = SD.COD_STATUS
LEFT JOIN TB_MEDIO_STATUS MS ON MS.COD_MEDIO_STATUS = SP.COD_MEDIO_STATUS
LEFT JOIN #TB_PROCESSO TT ON TT.COD_PROCESSO = TP.COD_PROCESSO
LEFT JOIN (
SELECT D.COD_CONTRATO_RELACIONADO, COUNT(COD_CONTRATO_RELACIONADO) AS cnt
FROM TB_DEMANDA D
INNER JOIN TB_PROCESSO P ON D.COD_CONTRATO_RELACIONADO = P.NUM_CONTRATO
GROUP BY D.COD_CONTRATO_RELACIONADO
) sq ON sq.COD_CONTRATO_RELACIONADO = DM.COD_CONTRATO_RELACIONADO
GROUP BY
TF.COD_FORNECEDOR,
TF.NOM_FANTASIA,
DM.COD_CONTRATO_RELACIONADO,
UA2.NOM_USUARIO,
sq.cnt
ORDER BY TF.NOM_FANTASIA
I integrated the num_aditivo subquery in a LEFT JOIN.

Conditional INNER JOIN in SQL Server

I have a rather complex query that pretty much mimics a test query I have below:
SELECT C.*
FROM Customer C
INNER JOIN CustDetail CD ON C.CustomerId = CD.CustomerId
INNER JOIN Address A ON CD.DetailID = A.DetailID
INNER JOIN Group G ON C.CustomerId = G.CustomerId --Join only when C.code = 1
INNER JOIN GroupDetail D ON G.GroupId = D.DetailId --Join only when C.code = 1
WHERE G.Active = 1 AND --Only when C.code = 1
D.code = '1' AND --Only when C.code = 1
C.Id = #customerId
I'd like to do INNER JOINs on Group G and GroupDetail D (and ofcourse not have them in the WHERE conditions based on the table column C.code = 1
I replaced the INNER JOINs with LEFT OUTER JOINs for both the join conditions, but the result set is not what was expected
How do I conditionally do the JOIN
SELECT C.*
FROM Customer C
INNER JOIN CustDetail CD ON C.CustomerId = CD.CustomerId
INNER JOIN Address A ON CD.DetailID = A.DetailID
LEFT OUTER JOIN Group G ON C.CustomerId = G.CustomerId
LEFT OUTER JOIN GroupDetail D ON G.GroupId = D.DetailId
WHERE ((G.Active = 1 AND C.code = 1) OR G.Active IS NULL) AND
((D.code = '1' AND C.code = 1) OR D.code IS NULL) AND
C.Id = #customerId
I'm guessing you didn't include the IS NULL checks before so you never got to see rows where C.code <> 1 ?
You should check for NULL on a field that will never be null. This is almost always 'id', but it's not clear that you have a G.id or a D.id.
I'm guessing what you want is just a tighter ON clause, and a compound condition.
SELECT C.*
FROM Customer C
INNER JOIN CustDetail CD ON C.CustomerId = CD.CustomerId
INNER JOIN Address A ON CD.DetailID = A.DetailID
-- the next two joins happen only when c.code=1
-- their columns will be null when there is no match.
LEFT JOIN Group G ON C.CustomerId = G.CustomerId AND C.Code = 1
LEFT JOIN GroupDetail D ON G.GroupId = D.DetailId AND C.Code = 1
WHERE C.Id = #customerId AND --always check this
-- this condition is true if code is null or code isn't 1,
((C.code IS NULL or C.code <> 1)
-- or (if the code is 1), it is true if g.active and d.code
OR (G.Active = 1 AND D.code = '1'))
This will do a semi-join only when code is 1.
SELECT C.*
FROM Customer C
INNER JOIN CustDetail CD
ON C.CustomerId = CD.CustomerId
INNER JOIN Address A
ON CD.DetailID = A.DetailID
WHERE
C.Id = #customerId AND
(c.code != 1 OR
EXISTS(
SELECT NULL
FROM Group G
JOIN GroupDetail D ON G.GroupId = D.DetailId
WHERE
C.CustomerId = G.CustomerId AND
G.Active = 1 AND
D.code = '1'
))