请求优化时出现语法错误

时间:2015-04-21 08:03:54

标签: sql sql-server

我正在尝试优化SQL查询,但我遇到了一个奇怪的问题。

这是我的优化请求:

SELECT proj.ProjetId AS ProjetId,
                SUM (CASE WHEN modTrans.Code != 'FoO' THEN 1 ELSE 0 END)    AS  VAL1,
                SUM(CASE WHEN modTrans.Code = 'Foo' THEN 1 ELSE 0 END)  AS  VAL2
    FROM Projet.Projet proj
        INNER JOIN Workflow.PointControle ptCont 
            ON ptCont.ProjetId = proj.ProjetId
        INNER JOIN Workflow.PointControleModele ptContMod 
            ON ptContMod.PointControleModeleId = ptCont.PointControleModeleId
        INNER JOIN Commande.CommandeTAC cdeTAC
            ON cdeTAC.ProjetId = proj.ProjetId
        INNER JOIN Commande.CommandeTACCatalogue cdeTACCat
            ON cdeTACCat.CommandeTACId = cdeTAC.CommandeTACId
        INNER JOIN Fournisseur.Fournisseur four
            ON four.FournisseurId = cdeTACCat.FournisseurId
        INNER JOIN Fournisseur.ModeTransmission modTrans
            ON modTrans.ModeTransmissionId = four.ModeTransmissionId
    WHERE ptContMod.PointControleModeleCode = 'FFooooooooo'
        AND ptCont.Etat = 'Foooooo'
        AND proj.DateLivraison IS NOT NULL
        AND [proj].[DateLivraison] <= DATEADD(DAY, 14, GETDATE())
    GROUP BY proj.ProjetId
    HAVING COUNT(VAL1) > 0 AND COUNT(VAL2) = 0

我收到了这个错误:

  

列名无效:'VAL1'列名无效:'VAL2'

错误发生在HAVING部分。 阅读本文档后,我不明白为什么会出现错误,因为我尊重语法:http://www.w3schools.com/sql/sql_having.asp

您可以在此处找到未经优化的完整请求:

BEGIN
    WITH Trans(VAL1, VAL2, projetId) AS
    (
        SELECT SUM (CASE WHEN modTrans.Code != 'Foo' THEN 1 ELSE 0 END) AS  NbNonSALM
                , SUM(CASE WHEN modTrans.Code = 'Foo' THEN 1 ELSE 0 END)    AS  NbSALM
                , proj.ProjetId AS projetId
        FROM Projet.Projet proj
        INNER JOIN Workflow.PointControle ptCont 
            ON ptCont.ProjetId = proj.ProjetId
        INNER JOIN Workflow.PointControleModele ptContMod 
            ON ptContMod.PointControleModeleId = ptCont.PointControleModeleId
        INNER JOIN Commande.CommandeTAC cdeTAC
            ON cdeTAC.ProjetId = proj.ProjetId
        INNER JOIN Commande.CommandeTACCatalogue cdeTACCat
            ON cdeTACCat.CommandeTACId = cdeTAC.CommandeTACId
        INNER JOIN Fournisseur.Fournisseur four
            ON four.FournisseurId = cdeTACCat.FournisseurId
        INNER JOIN Fournisseur.ModeTransmission modTrans
            ON modTrans.ModeTransmissionId = four.ModeTransmissionId
        WHERE ptContMod.PointControleModeleCode = 'Foooooo'
            AND ptCont.Etat = 'Fooo'
            AND proj.DateLivraison IS NOT NULL
            AND DATEADD(DAY, -14, proj.DateLivraison) <= GETDATE()
        GROUP BY proj.ProjetId  
    )

    SELECT proj.ProjetId AS ProjetId
    FROM Projet.Projet proj
        INNER JOIN Workflow.PointControle ptCont 
            ON ptCont.ProjetId = proj.ProjetId
        INNER JOIN Workflow.PointControleModele ptContMod 
            ON ptContMod.PointControleModeleId = ptCont.PointControleModeleId
        INNER JOIN Commande.CommandeTAC cdeTAC
            ON cdeTAC.ProjetId = proj.ProjetId
        INNER JOIN Commande.CommandeTACCatalogue cdeTACCat
            ON cdeTACCat.CommandeTACId = cdeTAC.CommandeTACId
        INNER JOIN Fournisseur.Fournisseur four
            ON four.FournisseurId = cdeTACCat.FournisseurId
        INNER JOIN Fournisseur.ModeTransmission modTrans
            ON modTrans.ModeTransmissionId = four.ModeTransmissionId
        INNER JOIN Trans ON Trans.projetId = proj.ProjetId
    WHERE ptContMod.PointControleModeleCode = 'Foo'
        AND ptCont.Etat = 'Fooo'
        AND proj.DateLivraison IS NOT NULL
        AND DATEADD(DAY, -14, proj.DateLivraison) <= GETDATE()
    GROUP BY proj.ProjetId
    HAVING COUNT(trans.NbNonSALM) > 0 AND COUNT(trans.NbSALM) = 0

    UNION

    SELECT projet.ProjetId AS ProjetId
    FROM Projet.Projet projet
        INNER JOIN Workflow.PointControle ptControle 
                ON ptControle.ProjetId = projet.ProjetId
        INNER JOIN Workflow.PointControleModele ptContMod 
                ON ptContMod.PointControleModeleId = ptControle.PointControleModeleId
        INNER JOIN Commande.CommandeTAC cdeTAC
                ON cdeTAC.ProjetId = projet.ProjetId
        INNER JOIN Commande.CommandeTACCatalogue cdeTACCat
                ON cdeTACCat.CommandeTACId = cdeTAC.CommandeTACId
        INNER JOIN commande.AREntete arEnt
                ON arEnt.ProjetIdTAC = cdeTAC.ProjetIdTAC
        INNER JOIN Commande.Article art
                ON art.AREnteteId = arEnt.AREnteteId AND art.CommandeTACCatalogueId = cdeTACCat.CommandeTACCatalogueId
        INNER JOIN Fournisseur.Fournisseur four
                ON four.FournisseurId = cdeTACCat.FournisseurId
        INNER JOIN Fournisseur.ModeTransmission modTrans
                ON modTrans.ModeTransmissionId = four.ModeTransmissionId
    WHERE ptContMod.PointControleModeleCode = 'Fooo'
        AND ptControle.Etat = 'Foo'
        AND arEnt.SuppressionLogique = 0
        AND arEnt.Statut IS NOT NULL
        AND arEnt.Statut >= 4
        AND arEnt.Statut != 9
        AND modTrans.Code = 'Fooooooo'
        AND projet.SiteId = @siteId
END
;

3 个答案:

答案 0 :(得分:1)

您无法在HAVING子句中使用别名。替换为:

HAVING 
    SUM(CASE WHEN modTrans.Code != 'FoO' THEN 1 ELSE 0 END) > 0 
    AND SUM(CASE WHEN modTrans.Code = 'Foo' THEN 1 ELSE 0 END) = 0

答案 1 :(得分:1)

我不是试试这个,但我觉得它对你有用..或者如果出现错误,你可以提供一些样本数据。

;WITH CTE AS
(
SELECT proj.ProjetId AS ProjetId,
                SUM (CASE WHEN modTrans.Code != 'FoO' THEN 1 ELSE 0 END)    AS  VAL1,
                SUM(CASE WHEN modTrans.Code = 'Foo' THEN 1 ELSE 0 END)  AS  VAL2
    FROM Projet.Projet proj
        INNER JOIN Workflow.PointControle ptCont 
            ON ptCont.ProjetId = proj.ProjetId
        INNER JOIN Workflow.PointControleModele ptContMod 
            ON ptContMod.PointControleModeleId = ptCont.PointControleModeleId
        INNER JOIN Commande.CommandeTAC cdeTAC
            ON cdeTAC.ProjetId = proj.ProjetId
        INNER JOIN Commande.CommandeTACCatalogue cdeTACCat
            ON cdeTACCat.CommandeTACId = cdeTAC.CommandeTACId
        INNER JOIN Fournisseur.Fournisseur four
            ON four.FournisseurId = cdeTACCat.FournisseurId
        INNER JOIN Fournisseur.ModeTransmission modTrans
            ON modTrans.ModeTransmissionId = four.ModeTransmissionId
    WHERE ptContMod.PointControleModeleCode = 'FFooooooooo'
        AND ptCont.Etat = 'Foooooo'
        AND proj.DateLivraison IS NOT NULL
        AND [proj].[DateLivraison] <= DATEADD(DAY, 14, GETDATE())
    GROUP BY proj.ProjetId
) 
SELECT ProjetId, VAL1, VAL2
FROM CTE 
GROUP BY ProjetId, VAL1, VAL2
HAVING COUNT(VAL1) > 0 AND COUNT(VAL2) = 0

答案 2 :(得分:0)

用此

替换您的HAVING子句
HAVING
SUM (CASE WHEN modTrans.Code != 'FoO' THEN 1 ELSE 0 END)>0
AND
SUM(CASE WHEN modTrans.Code = 'Foo' THEN 1 ELSE 0 END)=0