“WHERE”절에 “CASE”문이 포함 된 쿼리로 작업하고 있습니다. 그러나 SQL Server 2008을 실행하는 동안 오류가 발생합니다. 누구든지 올바른 쿼리로 나를 도울 수 있습니까? 다음은 쿼리입니다.
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
답변
먼저 CASE
문은 표현식 자체가 아니라 표현식의 일부 여야 합니다.
즉, 다음을 가질 수 있습니다.
WHERE co.DTEntered = CASE
WHEN LEN('blah') = 0
THEN co.DTEntered
ELSE '2011-01-01'
END
그러나 다음과 같이 작성한 방식으로는 작동하지 않습니다.
WHERE
CASE LEN('TestPerson')
WHEN 0 THEN co.personentered = co.personentered
ELSE co.personentered LIKE '%TestPerson'
END
다음과 같이 결합 된 OR 문을 사용하면 더 좋은 결과를 얻을 수 있습니다.
WHERE (
(LEN('TestPerson') = 0
AND co.personentered = co.personentered
)
OR
(LEN('TestPerson') <> 0
AND co.personentered LIKE '%TestPerson')
)
어느 쪽이든 나는 당신이 얻을 쿼리 계획이 얼마나 좋은지 잘 모르겠습니다. WHERE
절 에서 이러한 유형의 헛소리 는 종종 쿼리 최적화 프로그램이 인덱스를 사용하지 못하게합니다.
답변
이것은 당분간 귀하의 문제를 해결해야하지만 좋은 접근 방식이 아니라는 점을 상기시켜야합니다.
WHERE
CASE LEN('TestPerson')
WHEN 0 THEN
CASE WHEN co.personentered = co.personentered THEN 1 ELSE 0 END
ELSE
CASE WHEN co.personentered LIKE '%TestPerson' THEN 1 ELSE 0 END
END = 1
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 CASE WHEN co.DTEntered = co.DTEntered THEN 1 ELSE 0 END
ELSE
CASE LEN('2012-01-09 11:56:29.327')
WHEN 0 THEN
CASE WHEN co.DTEntered >= '2011-01-09 11:56:29.327' THEN 1 ELSE 0 END
ELSE
CASE WHEN co.DTEntered BETWEEN '2011-01-09 11:56:29.327'
AND '2012-01-09 11:56:29.327'
THEN 1 ELSE 0 END
END
END = 1
AND tl.storenum < 699
답변
다음을 시도하십시오.
select * From emp_master
where emp_last_name=
case emp_first_name
when 'test' then 'test'
when 'Mr name' then 'name'
end
답변
쿼리의 시작 부분이 다음과 같아야한다고 생각합니다.
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
WHEN (LEN([TestPerson]) = 0 AND co.personentered = co.personentered) OR (LEN([TestPerson]) <> 0 AND co.personentered LIKE '%'+TestPerson) THEN 1
ELSE 0
END = 1
AND
그러나
꼬리에있는 것은 완전히 이해할 수 없다
답변
다음 WHERE
과 같이 작성할 수 있습니다.
WHERE
(LEN('TestPerson') <> 0 OR co.personentered = co.personentered) AND
(LEN('TestPerson') = 0 OR co.personentered LIKE '%TestPerson') AND
(cc.ccnum = CASE LEN('TestFFNum')
WHEN 0 THEN cc.ccnum
ELSE 'TestFFNum'
END ) AND
(LEN('2011-01-09 11:56:29.327') <> 0 OR co.DTEntered = co.DTEntered ) AND
((LEN('2011-01-09 11:56:29.327') = 0 AND LEN('2012-01-09 11:56:29.327') <> 0) OR co.DTEntered >= '2011-01-09 11:56:29.327' ) AND
((LEN('2011-01-09 11:56:29.327') = 0 AND LEN('2012-01-09 11:56:29.327') = 0) OR co.DTEntered BETWEEN '2011-01-09 11:56:29.327' AND '2012-01-09 11:56:29.327' ) AND
tl.storenum < 699
답변
예를 들어 아래와 같이 시도 할 수도 있습니다. 아웃 바운드 배송 만 표시
SELECT shp_awb_no,shpr_ctry_cd, recvr_ctry_cd,
CASE WHEN shpr_ctry_cd = record_ctry_cd
THEN "O"
ELSE "I"
END AS route
FROM shipment_details
WHERE record_ctry_cd = "JP"
AND "O" = CASE WHEN shpr_ctry_cd = record_ctry_cd
THEN "O"
ELSE "I"
END
답변
이 질문에 감사드립니다. 실제로 나는 아래 쿼리에있는 다른 것을 찾고 있습니다. 이것은 누군가를 도울 수 있습니다.
SELECT DISTINCT CASE WHEN OPPORTUNITY='' THEN '(BLANK)' ELSE OPPORTUNITY END
AS OPP,LEN(OPPORTUNITY) FROM [DBO].[TBL]
위의 쿼리는 빈 값이 “(blank)”로 표시되는 드롭 다운을 채우는 것입니다. 또한이 값을 sql where 절에 전달하여 다른 값과 함께 빈 값을 가져 오면 처리 방법을 모르겠습니다. 그리고 마침내 이것은 누군가에게 도움이 될 수있는 아래 해결책을 제시했습니다.
여기있어 ,
DECLARE @OPP TABLE (OPP VARCHAR(100))
INSERT INTO @OPP VALUES('(BLANK)'),('UNFUNDED'),('FUNDED/NOT COMMITTED')
SELECT DISTINCT [OPPORTUNITY]
FROM [DBO].[TBL] WHERE ( CASE WHEN OPPORTUNITY ='' THEN '(BLANK)' ELSE OPPORTUNITY END IN (SELECT OPP FROM @OPP))
ORDER BY 1