집 >데이터 베이스 >MySQL 튜토리얼 >SQL Server 2008의 WHERE 절 내에서 CASE 문을 올바르게 사용하려면 어떻게 해야 합니까?
SQL Server 2008 WHERE 절의 CASE 문 문제 해결
SQL Server 2008에서는 WHERE 절 내에 CASE 문을 사용하는 것이 어려울 수 있습니다. 다음 쿼리는 일반적인 문제를 보여줍니다.
<code class="language-sql">SELECT tl.storenum 'Store #', co.ccnum 'FuelFirst Card #', co.dtentered 'Date Entered', CASE st.reasonid WHEN 1 THEN 'Active' WHEN 2 THEN 'Not Active' WHEN 0 THEN st.ccstatustypename ELSE 'Unknown' END 'Status', CASE st.ccstatustypename WHEN 'Active' THEN ' ' WHEN 'Not Active' THEN ' ' ELSE st.ccstatustypename END 'Reason', UPPER(REPLACE(REPLACE(co.personentered,'RT\\',''),'RACETRAC\\','')) 'Person Entered', co.comments 'Comments or Notes' FROM comments co INNER JOIN cards cc ON co.ccnum=cc.ccnum INNER JOIN customerinfo ci ON cc.customerinfoid=ci.customerinfoid INNER JOIN ccstatustype st ON st.ccstatustypeid=cc.ccstatustypeid INNER JOIN customerstatus cs ON cs.customerstatuscd=ci.customerstatuscd INNER JOIN transactionlog tl ON tl.transactionlogid=co.transactionlogid LEFT JOIN stores s ON s.StoreNum = tl.StoreNum WHERE CASE LEN('TestPerson') WHEN 0 THEN co.personentered = co.personentered ELSE co.personentered LIKE '%TestPerson' END AND cc.ccnum = CASE LEN('TestFFNum') WHEN 0 THEN cc.ccnum ELSE 'TestFFNum' END AND CASE LEN('2011-01-09 11:56:29.327') WHEN 0 THEN co.DTEntered = co.DTEntered ELSE CASE LEN('2012-01-09 11:56:29.327') WHEN 0 THEN co.DTEntered >= '2011-01-09 11:56:29.327' ELSE co.DTEntered BETWEEN '2011-01-09 11:56:29.327' AND '2012-01-09 11:56:29.327' END END AND tl.storenum < 699 ORDER BY tl.StoreNum</code>
해결책: 부울 논리를 사용한 리팩토링
핵심 문제는 WHERE 절의 조건부 논리 내에서 직접 CASE 문을 부적절하게 사용한다는 것입니다. CASE 표현식은 값을 생성해야 합니다. 전체 조건이 되어서는 안 됩니다.
해결 방법은 AND
및 OR
연산자를 사용하여 CASE 문을 동등한 부울 논리로 바꾸는 것입니다.
<code class="language-sql">SELECT tl.storenum 'Store #', co.ccnum 'FuelFirst Card #', co.dtentered 'Date Entered', CASE st.reasonid WHEN 1 THEN 'Active' WHEN 2 THEN 'Not Active' WHEN 0 THEN st.ccstatustypename ELSE 'Unknown' END 'Status', CASE st.ccstatustypename WHEN 'Active' THEN ' ' WHEN 'Not Active' THEN ' ' ELSE st.ccstatustypename END 'Reason', UPPER(REPLACE(REPLACE(co.personentered,'RT\\',''),'RACETRAC\\','')) 'Person Entered', co.comments 'Comments or Notes' FROM comments co INNER JOIN cards cc ON co.ccnum=cc.ccnum INNER JOIN customerinfo ci ON cc.customerinfoid=ci.customerinfoid INNER JOIN ccstatustype st ON st.ccstatustypeid=cc.ccstatustypeid INNER JOIN customerstatus cs ON cs.customerstatuscd=ci.customerstatuscd INNER JOIN transactionlog tl ON tl.transactionlogid=co.transactionlogid LEFT JOIN stores s ON s.StoreNum = tl.StoreNum WHERE (LEN('TestPerson') = 0 AND co.personentered = co.personentered) OR (LEN('TestPerson') > 0 AND co.personentered LIKE '%TestPerson') AND ((LEN('TestFFNum') = 0 AND cc.ccnum = cc.ccnum) OR (LEN('TestFFNum') > 0 AND cc.ccnum = 'TestFFNum')) AND ((LEN('2011-01-09 11:56:29.327') = 0 AND co.DTEntered = co.DTEntered) OR (LEN('2012-01-09 11:56:29.327') = 0 AND co.DTEntered >= '2011-01-09 11:56:29.327') OR (co.DTEntered BETWEEN '2011-01-09 11:56:29.327' AND '2012-01-09 11:56:29.327')) AND tl.storenum < 699 ORDER BY tl.StoreNum;</code>
성능 향상
이 수정된 쿼리는 올바르게 작동하지만 성능은 더욱 향상될 수 있습니다.
OR
조건은 효율성이 떨어질 수 있습니다. 대체 쿼리 구조를 고려하세요(예: 고유한 검색 기준에 UNION ALL
사용).WHERE
절에서 자주 사용되는 열(예: co.personentered
, cc.ccnum
, co.DTEntered
, tl.storenum
)에 인덱스가 있는지 확인하세요.이러한 점을 해결하면 보다 효율적이고 읽기 쉬운 SQL 쿼리를 만들 수 있습니다.
위 내용은 SQL Server 2008의 WHERE 절 내에서 CASE 문을 올바르게 사용하려면 어떻게 해야 합니까?의 상세 내용입니다. 자세한 내용은 PHP 중국어 웹사이트의 기타 관련 기사를 참조하세요!