如何以复杂的方式使用案例
Posted
技术标签:
【中文标题】如何以复杂的方式使用案例【英文标题】:How use case in complex way 【发布时间】:2021-07-09 20:59:05 【问题描述】:我有一个新案例要添加到我的查询中,它显着改变了我的 sql 的方式,并且可能需要案例语句,但我不确定如何将我现在想做的联合作为结合起来案例陈述。案例表和概念表非常大/慢,最好不要单独/两次加入它们。但是,新的查询部分不需要 #tempCMs、external_user_data 或 cm.first/lastName 或 cm.user_id。一个有 queueName,另一个没有。每个都有不同的主题。有没有人知道如何组合查询以避免两次命中慢表?
这是存储过程的旧部分:
SELECT distinct
c.id
,uc.id
,cm.FIRSTNAME as CM_first
,cm.LASTNAME as CM_last
,cm.user_id as cm_userid
,c.person_id
,eou.external_id--eou.external_id AS CM_ExternalUserId
,c.id+' '+' Query1' AS subject
,emd.externalId externalPersonId
,eou.system_id as externalSystemId
,'' --no queue passed for this area
FROM
#tempCMs CM with (NOLOCK)
INNER JOIN dbo.CASES c with (NOLOCK) ON CM.Personid=c.id
INNER JOIN dbo.UM_CASE uc with (NOLOCK) ON uc.case_id=c.id
INNER JOIN dbo.LOS S WITH (NOLOCK) ON S.case_id = UC.case_id
INNER JOIN dbo.LOS_EXTENSION SC WITH (NOLOCK) ON SC.los_id= S.id
INNER JOIN dbo.USER u with (NOLOCK) on u.id=cm.user_id --
INNER JOIN dbo.PERSON op with (NOLOCK) on op.id=c.Person_id
INNER JOIN dbo.U_MEMBER_CONCEPT MC ON MC.CID = op.cid
INNER JOIN dbo.EXTERNAL_USER_DATA eou with (NOLOCK) ON eou.user_id = cm.user_id --
INNER JOIN dbo.EXTERNAL_MEMBER_DATA emd with (NOLOCK) ON emd.CID = op.cid
WHERE
u.disable <> 1 --not disabled/inactive user
AND
--not external case manager
(cm.firstname not like '%external%' and cm.lastname not like '%case manager%')
AND
(
C.ID in (SELECT case_id FROM #CASES where concept_id='501620')
)
这是新的联合部分:
UNION
SELECT DISTINCT
c.id
,uc.id
,''--cm.FIRSTNAME as CM_first --?
,''--cm.LASTNAME as CM_last --?
,''--cm.user_id as cm_userid --?
,c.person_id
,'' --not needed for this case
,c.id+' '+' Query2' AS subject
,emd.externalId externalPersonId
,''--not needed
,'queueName' AS externalQueue --new admission for this case
FROM
--#tempCMs CM with (NOLOCK)
dbo.CASES c with (NOLOCK)
INNER JOIN dbo.UM_CASE uc with (NOLOCK) ON uc.case_id=c.id
INNER JOIN dbo.LOS S WITH (NOLOCK) ON S.case_id = UC.case_id
INNER JOIN dbo.LOS_EXTENSION SC WITH (NOLOCK) ON SC.los_id= S.id
--INNER JOIN dbo.USER u with (NOLOCK) on u.id=cm.user_id
INNER JOIN dbo.PERSON op with (NOLOCK) on op.id=c.Person_id
INNER JOIN dbo.U_MEMBER_CONCEPT MC with (NOLOCK) ON MC.CID = op.cid
--INNER JOIN dbo.EXTERNAL_USER_DATA eou with (NOLOCK) ON eou.user_id = cm.user_id --??don't need/cm
INNER JOIN dbo.EXTERNAL_MEMBER_DATA emd with (NOLOCK) ON emd.CID = op.cid
INNER JOIN dbo.UM_SERVICE sv (NOLOCK) ON sv.case_id = uc.case_id --different here
WHERE
(
sv.diag_code in (SELECT * FROM dbo.T_CAE1350_diag_codes_Indicator)
)
AND --member not already handled
(
C.person_ID not in (select person_id from #tempCMs )
)
这样的表设置:
CASES
id person_id
UM_CASE
case_id
LOS
case_id id
LOS_EXTENSION
los_id
Person
id cid
U_MEMBER_CONCEPT
cid
EXTERNAL_USER_DATA
cid user_id
EXERNAL_Member_data
cid
UM_SERVICE
case_id diag_code
USER
id first_name last_name
CREATE TABLE #tempCMs
(
CASEID VARCHAR(12),
Person_id int,
id VARCHAR(25),
user_id int,
LASTNAME VARCHAR(150),
FIRSTNAME VARCHAR(150)
)
INSERT INTO #tempCMs(CASEID,Person_id, id, user_id, lastname, firstname)
SELECT case_id,person_id, id, ccv.user_id, u.LAST_NAME, u.FIRST_NAME
FROM dbo.CM_CASES_VIEW ccv
inner join dbo.USER u with (nolock) on ccv.user_id=u.id
CM_CASES_VIEW
user_id person_id case_id
SELECT DISTINCT C.ID AS CASE_ID
,mcv.concept_id
,mcv.STR_VALUE
INTO #CASES
FROM
dbo.CASES C
INNER JOIN dbo.UM_CASE UC (NOLOCK) ON C.ID = UC.case_id
INNER JOIN dbo.PERSON OP (NOLOCK) ON C.person_id = OP.ID
INNER JOIN dbo.U_MEMBER_CONCEPT MCV (NOLOCK) ON OP.CID = MCV.CID
我不确定要在网上搜索什么来回答这个问题,因为它非常复杂。非常感谢您的任何想法!
**更新星期六...你怎么看?这是否可以很好地处理慢表,但将信息输入 cte 并稍后使用?
;with commonElement_cte as(
SELECT DISTINCT
c.id
,uc.id as ucid
,uc.case_id
,c.person_id
,c.id+' '+' Query2' AS subject
,emd.externalId externalPersonId
FROM
dbo.CASES c with (NOLOCK)
INNER JOIN dbo.UM_CASE uc with (NOLOCK) ON uc.case_id=c.id
INNER JOIN dbo.LOS S WITH (NOLOCK) ON S.case_id = UC.case_id
INNER JOIN dbo.LOS_EXTENSION SC WITH (NOLOCK) ON SC.los_id= S.id
--INNER JOIN dbo.USER u with (NOLOCK) on u.id=cm.user_id
INNER JOIN dbo.PERSON op with (NOLOCK) on op.id=c.Person_id
INNER JOIN dbo.U_MEMBER_CONCEPT MC with (NOLOCK) ON MC.CID = op.cid
INNER JOIN dbo.EXTERNAL_MEMBER_DATA emd with (NOLOCK) ON emd.CID = op.cid
) --common Element cte
select
SELECT distinct
ce.id
,ce.ucid
,cm.FIRSTNAME as CM_first
,cm.LASTNAME as CM_last
,cm.user_id as cm_userid
,ce.person_id
,ce.external_id--eou.external_id AS CM_ExternalUserId
,ce.id+' '+' Query1' AS subject
,ce.externalId externalPersonId
,eou.system_id as externalSystemId
,'' --no queue passed for this area
FROM
commonElement_cte ce
INNER JOIN #tempCMs CM on CM.person_ID=ce.person_ID
INNER JOIN dbo.USER u with (NOLOCK) on u.id=cm.user_id --
INNER JOIN dbo.EXTERNAL_USER_DATA eou with (NOLOCK) ON eou.user_id = cm.user_id --
WHERE
u.disable <> 1 --not disabled/inactive user
AND
--not external case manager
(cm.firstname not like '%external%' and cm.lastname not like '%case manager%')
AND
(
ce.ID in (SELECT case_id FROM #CASES where concept_id='501620')
)
Here's new union part:
UNION
SELECT DISTINCT
ce.id
,ce.ucid
,''--cm.FIRSTNAME as CM_first --?
,''--cm.LASTNAME as CM_last --?
,''--cm.user_id as cm_userid --?
,ce.person_id
,'' --not needed for this case
,ce.id+' '+' Query2' AS subject
,ce.externalId externalPersonId
,''--not needed
,'queueName' AS externalQueue --new admission for this case
FROM
commonElement_cte ce
INNER JOIN dbo.UM_SERVICE sv (NOLOCK) ON sv.case_id = ce.case_id --different here
WHERE
(
sv.diag_code in (SELECT * FROM dbo.T_CAE1350_diag_codes_Indicator)
)
AND --member not already handled
(
ce.person_ID not in (select person_id from #tempCMs )
)
【问题讨论】:
#tempCMs CM with (NOLOCK)
仅此一项就告诉我,编写此代码的人并没有真正理解该提示。您的组织不应使用nolock 散布代码。
但是您在描述中使用 CASE 似乎将 TSQL 函数(这是一个标量表达式)与您的 CASE 业务实体混淆了。有用的建议需要更详细地了解您的架构和用法。也许您应该首先专注于创建一个正确且有效的查询,然后尝试对其进行优化?
抱歉错字。将案例表更改为案例...我重命名了一些表名以使其更清晰。请不要专注于 nolock ...专注于结合两个查询的问题。旧查询肯定有效。
如果旧查询运行,这意味着您没有将其复制到您的问题中...FROM #tempCMs CM with (NOLOCK) and CM.status in ('1','4')
会给出语法错误;你不能把and
放在那里。
我去掉了 1/4 部分。
【参考方案1】:
您是否检查了执行计划以了解减速的原因?
您似乎正在扫描 CASES 和 U_MEMBER_CONCEPT 各 3 次。一次填充#CASES,一次在您的每个查询中。这个怎么样:
SELECT DISTINCT C.ID AS CASE_ID
, uc.id
, mcv.concept_id
, mcv.STR_VALUE
, c.person_ID
, op.cid
INTO #CASES
FROM dbo.CASES C
INNER JOIN dbo.UM_CASE UC ON C.ID = UC.case_id
INNER JOIN dbo.PERSON OP ON C.person_id = OP.ID
INNER JOIN dbo.U_MEMBER_CONCEPT MCV ON OP.CID = MCV.CID
如果可能的话,我建议添加一个WHERE
子句。
SELECT distinct
c.case_id
, c.id
, cm.FIRSTNAME as CM_first
, cm.LASTNAME as CM_last
, cm.user_id as cm_userid
, c.person_id
, eou.external_id--eou.external_id AS CM_ExternalUserId
, c.id+' '+' Query1' AS subject
, emd.externalId externalPersonId
, eou.system_id as externalSystemId
, '' --no queue passed for this area
FROM #tempCMs CM
INNER JOIN #CASES c ON CM.Personid=c.id
--INNER JOIN dbo.UM_CASE uc with (NOLOCK) ON uc.case_id=c.id
INNER JOIN dbo.LOS S WITH (NOLOCK) ON S.case_id = UC.case_id
INNER JOIN dbo.LOS_EXTENSION SC WITH (NOLOCK) ON SC.los_id= S.id
INNER JOIN dbo.USER u with (NOLOCK) on u.id=cm.user_id --
--INNER JOIN dbo.PERSON op with (NOLOCK) on op.id=c.Person_id
--INNER JOIN dbo.U_MEMBER_CONCEPT MC ON MC.CID = op.cid
INNER JOIN dbo.EXTERNAL_USER_DATA eou with (NOLOCK) ON eou.user_id = cm.user_id --
INNER JOIN dbo.EXTERNAL_MEMBER_DATA emd with (NOLOCK) ON emd.CID = c.cid
WHERE u.disable <> 1 --not disabled/inactive user
AND cm.firstname not like '%external%'
and cm.lastname not like '%case manager%'
AND C.concept_id='501620'
UNION
SELECT DISTINCT
c.case_id
, c.id
, ''--cm.FIRSTNAME as CM_first --?
, ''--cm.LASTNAME as CM_last --?
, ''--cm.user_id as cm_userid --?
, c.person_id
, '' --not needed for this case
, c.id+' '+' Query2' AS subject
, emd.externalId externalPersonId
, ''--not needed
, 'queueName' AS externalQueue --new admission for this case
FROM #CASES c
--INNER JOIN dbo.UM_CASE uc with (NOLOCK) ON uc.case_id=c.id
INNER JOIN dbo.LOS S WITH (NOLOCK) ON S.case_id = UC.case_id
INNER JOIN dbo.LOS_EXTENSION SC WITH (NOLOCK) ON SC.los_id= S.id
--INNER JOIN dbo.USER u with (NOLOCK) on u.id=cm.user_id
--INNER JOIN dbo.PERSON op with (NOLOCK) on op.id=c.Person_id
--INNER JOIN dbo.U_MEMBER_CONCEPT MC with (NOLOCK) ON MC.CID = op.cid
--INNER JOIN dbo.EXTERNAL_USER_DATA eou with (NOLOCK) ON eou.user_id = cm.user_id --??don't need/cm
INNER JOIN dbo.EXTERNAL_MEMBER_DATA emd with (NOLOCK) ON emd.CID = c.cid
INNER JOIN dbo.UM_SERVICE sv (NOLOCK) ON sv.case_id = uc.case_id --different here
WHERE sv.diag_code in (SELECT * FROM dbo.T_CAE1350_diag_codes_Indicator) -- It is very unlikely this will work.
AND C.person_ID not in (select person_id from #tempCMs)
并且不要使用SELECT *
。永远。
【讨论】:
谢谢!我喜欢这个主意!最好不要使用 select *.我也会尝试为 #cases 找到 where 子句。 :)以上是关于如何以复杂的方式使用案例的主要内容,如果未能解决你的问题,请参考以下文章