Sql 替换为存在或计数。怎么做。这里少了什么?

Sql 替换为存在或计数。怎么做。这里少了什么?,sql,sql-server,database,tsql,Sql,Sql Server,Database,Tsql,我在一个部分的中间使用查询关键字。因为我正在使用嵌套查询,并且由于我的前辈告诉我可能出现的性能问题,我想用Exists替换 我是否缺少某个列,即您在此查询中要查找的内容。为了便于阅读,此查询包含一些别名。 我怎样才能删除它 SELECT TX.PK_MAP_ID AS MAP_ID , MG.PK_GUEST_ID AS Guest_Id , MG.FIRST_NAME , H.PK_CATEGORY_ID AS Preference_Id

我在一个部分的中间使用查询关键字。因为我正在使用嵌套查询,并且由于我的前辈告诉我可能出现的性能问题,我想用
Exists
替换

我是否缺少某个列,即您在此查询中要查找的内容。为了便于阅读,此查询包含一些别名。

我怎样才能删除它

SELECT  TX.PK_MAP_ID AS MAP_ID 
        , MG.PK_GUEST_ID AS Guest_Id 
        , MG.FIRST_NAME 
        , H.PK_CATEGORY_ID AS Preference_Id 
        , H.DESCRIPTION AS Preference_Name 
        , H.FK_CATEGORY_ID AS Parent_Id 
        , H.IMMEDIATE_PARENT AS Parent_Name 
        , H.Department_ID 
        , H.Department_Name 
        , H.ID_PATH, H.DESC_PATH 
FROM          
    dbo.M_GUEST AS MG  
        LEFT OUTER JOIN 
    dbo.TX_MAP_GUEST_PREFERENCE AS TX  
            ON  
                (MG.PK_GUEST_ID = TX.FK_GUEST_ID) 
        LEFT OUTER JOIN 
    dbo.GetHierarchy_Table AS H  
            ON  
                (TX.FK_CATEGORY_ID = H.PK_CATEGORY_ID) 
WHERE      
    (MG.IS_ACTIVE = 1)  
        AND  
    (TX.IS_ACTIVE = 1)  
        AND  
    (H.Department_ID IN -----How to remove this IN operator with EXISTS or Count() 
              ( 
                SELECT C.PK_CATEGORY_ID AS DepartmentId 
                FROM  
                    dbo.TX_MAP_DEPARTMENT_OPERATOR AS D  
                        INNER JOIN 
                    dbo.M_OPERATOR AS M  
                            ON   
                                (D.FK_OPERATOR_ID = M.PK_OPERATOR_ID) 
                                    AND  
                                (D.IS_ACTIVE = M.IS_ACTIVE) 
                        INNER JOIN 
                    dbo.L_USER_ROLE AS R  
                            ON   
                                (M.FK_ROLE_ID = R.PK_ROLE_ID) 
                                    AND  
                                (M.IS_ACTIVE = R.IS_ACTIVE) 
                        INNER JOIN 
                    dbo.L_CATEGORY_TYPE AS C  
                            ON  
                                (D.FK_DEPARTMENT_ID = C.PK_CATEGORY_ID) 
                                    AND  
                                (D.IS_ACTIVE = C.IS_ACTIVE) 
                WHERE       
                    (D.IS_ACTIVE = 1)  
                        AND  
                    (M.IS_ACTIVE = 1)  
                        AND  
                    (R.IS_ACTIVE = 1)  
                        AND  
                    (C.IS_ACTIVE = 1)  
            )--END INNER QUERY 
    )--END Condition 

如果我用EXISTS或COUNT替换IN,可能会遇到哪些新问题?

基本上,我理解您的问题,您在问我如何替换此问题:

where H.department_id in (select departmentid from...)
为此:

where exists (select...) 
或者这个:

where (select count(*) from ...) > 1
这相当直截了当。一种方法可能是:

WHERE...
  AND EXISTS (select c.pk_category_id 
              from tx_map_department_operator d
                inner join m_operator as m
                  on    d.fk_operator_id = m.pk_operator_id
                inner join l_user_role l
                  on m.fk_role_id = r.pk_role_id
                inner join l_category_type c
                  on d.fk_department_id = c.pk_category_id
               where h.department_id = c.pk_category_id
                 and d.is_active = 1 
                 and m.is_active = 1 
                 and r.is_active = 1 
                 and c.is_active = 1
              )
我删除了处于活动状态的上的额外联接,因为它们是冗余的。您应该测试它如何使用索引运行,因为这样可能会更快。但我对此表示怀疑。但值得比较的是,添加join子句(
join on…和x.is\u active=y.is\u active
)还是检查where子句(
x.is\u active=1和y.is\u active=1和z.is\u active=1…

我建议您只使用
exists
,而不是
count(*)
,因为我知道exists应该在找到1行后停止,而count可能会继续执行,直到完成,然后与您的参考值进行比较(count>1)


另外,这是一个奇怪的列命名标准。主键是否有PK前缀,外键是否有FK前缀?我从未见过这种情况。

基本上,我理解你的问题,你是在问我如何替换这个:

where H.department_id in (select departmentid from...)
为此:

where exists (select...) 
或者这个:

where (select count(*) from ...) > 1
这相当直截了当。一种方法可能是:

WHERE...
  AND EXISTS (select c.pk_category_id 
              from tx_map_department_operator d
                inner join m_operator as m
                  on    d.fk_operator_id = m.pk_operator_id
                inner join l_user_role l
                  on m.fk_role_id = r.pk_role_id
                inner join l_category_type c
                  on d.fk_department_id = c.pk_category_id
               where h.department_id = c.pk_category_id
                 and d.is_active = 1 
                 and m.is_active = 1 
                 and r.is_active = 1 
                 and c.is_active = 1
              )
我删除了处于活动状态的上的额外联接,因为它们是冗余的。您应该测试它如何使用索引运行,因为这样可能会更快。但我对此表示怀疑。但值得比较的是,添加join子句(
join on…和x.is\u active=y.is\u active
)还是检查where子句(
x.is\u active=1和y.is\u active=1和z.is\u active=1…

我建议您只使用
exists
,而不是
count(*)
,因为我知道exists应该在找到1行后停止,而count可能会继续执行,直到完成,然后与您的参考值进行比较(count>1)


另外,这是一个奇怪的列命名标准。主键是否有PK前缀,外键是否有FK前缀?我从未见过这种情况。

是的,我认为命名标准也很烦人。SIN:我确实同意命名惯例有点荒谬,但我不是PM或TL,只是一个SE,所以不能改变它,必须按照告诉我们的方式来做,sry对此无能为力。我的问题是,撤销H部门会产生什么影响。我在这里想的是,如何得到相同的结果。我认为它应该加入到H表中。上面所做的更改。但现在我不确定我是否理解其意图。在内部查询中使用H表可能会大大降低速度。是的,我认为命名标准也很烦人。SIN:我确实同意命名惯例有点荒谬,但我不是PM或TL,只是一个SE,所以不能改变它,必须按照告诉我们的方式来做,sry对此无能为力。我的问题是,撤销H部门会产生什么影响。我在这里想的是,如何得到相同的结果。我认为它应该加入到H表中。上面所做的更改。但现在我不确定我是否理解其意图。在内部查询中使用H表可能会大大降低查询速度。