作者热门文章
- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
我有一个 Oracle SQL 查询,它在其列输出中包含计算。在这个简化的示例中,我们正在寻找日期在某个范围内的记录,其中某些字段与特定事物相匹配;然后对于这些记录,取 ID(不是唯一的)并再次搜索表以查找具有相同 ID 的记录,但某些字段与其他字段匹配并且日期在主记录的日期之前。然后返回最早的此类日期。以下代码完全按预期工作:
SELECT
TblA.ID, /* Not a primary key: there may be more than one record with the same ID */
(
SELECT
MIN(TblAAlias.SomeFieldDate)
FROM
TableA TblAAlias
WHERE
TblAAlias.ID = TblA.ID /* Here is the link reference to the main query */
TblAAlias.SomeField = 'Another Thing'
AND TblAAlias.SomeFieldDate <= TblA.SomeFieldDate /* Another link reference */
) AS EarliestDateOfAnotherThing
FROM
TableA TblA
WHERE
TblA.SomeField = 'Something'
AND TblA.SomeFieldDate BETWEEN TO_DATE('2015-01-01','YYYY-MM-DD') AND TO_DATE('2015-12-31','YYYY-MM-DD')
CASE WHEN
(
SELECT
MIN(TblAAlias.SomeFieldDate)
FROM
TableA TblAAlias
WHERE
TblAAlias.ID = TblA.ID /* Here is the link reference to the main query */
TblAAlias.SomeField = 'Another Thing'
AND TblAAlias.SomeFieldDate <= TblA.SomeFieldDate /* Another link reference */
) BETWEEN TO_DATE('2000-01-01','YYYY-MM-DD') AND TO_DATE('2004-12-31','YYYY-MM-DD')
THEN 'First period'
WHEN
(
SELECT
MIN(TblAAlias.SomeFieldDate)
FROM
TableA TblAAlias
WHERE
TblAAlias.ID = TblA.ID /* Here is the link reference to the main query */
TblAAlias.SomeField = 'Another Thing'
AND TblAAlias.SomeFieldDate <= TblA.SomeFieldDate /* Another link reference */
) BETWEEN TO_DATE('2005-01-01','YYYY-MM-DD') AND TO_DATE('2009-12-31','YYYY-MM-DD')
THEN 'Second period'
ELSE 'Last period'
END
''''' Note that this is pseudo-VBA not SQL:
Select case (Subquery which returns a date)
Case Between A and B
"Output 1"
Case Between C and D
"Output 2"
Case Between E and F
"Output 3"
End select
' ... etc
SELECT
APPLICANT.ID,
APPLICANT.FULL_NAME,
EarliestDate,
CASE
WHEN EarliestDate BETWEEN TO_DATE('2000-01-01','YYYY-MM-DD') AND TO_DATE('2004-12-31','YYYY-MM-DD') THEN 'First Period'
WHEN EarliestDate BETWEEN TO_DATE('2005-01-01','YYYY-MM-DD') AND TO_DATE('2009-12-31','YYYY-MM-DD') THEN 'Second Period'
WHEN EarliestDate >= TO_DATE('2010-01-01','YYYY-MM-DD') THEN 'Third Period'
END
FROM
/* Subquery in FROM - trying to get this to work */
(
SELECT
MIN(PERSON_EVENTS_Sub.REQUESTED_DTE) /* Earliest date of the secondary event */
FROM
EVENTS PERSON_EVENTS_Sub
WHERE
PERSON_EVENTS_Sub.PER_ID = APPLICANT.ID /* Link the person ID */
AND PERSON_EVENTS_Sub.DEL_IND IS NULL /* Not a deleted event */
AND PERSON_EVENTS_Sub.EVTYPE_SDV_VALUE IN (/* List of secondary events */)
AND PERSON_EVENTS_Sub.COU_SDV_VALUE = PERSON_EVENTS.COU_SDV_VALUE /* Another link from the subQ to the main query */
AND PERSON_EVENTS_Sub.REQUESTED_DTE <= PERSON_EVENTS.REQUESTED_DTE /* subQ event occurred before main query event */
AND ROWNUM = 1 /* To ensure only one record returned, in case multiple rows match the MIN date */
) /* And here - how would I alias the result of this subquery as "EarliestDate", for use above? */,
/* Then there are other tables from which to select */
EVENTS PERSON_EVENTS,
PEOPLE APPLICANT
WHERE
PERSON_EVENTS.PER_ID=APPLICANT.ID
AND PERSON_EVENTS.EVTYPE_SDV_VALUE IN (/* List of values - removed ID information */)
AND PERSON_EVENTS.REQUESTED_DTE BETWEEN '01-Jan-2014' AND '31-Jan-2014'
最佳答案
看 只有在重构现有查询时(而不是逻辑或功能上不同的方法)。
对我来说,最简单的方法就是将其作为嵌套查询执行...
- 内部查询将是您的基本查询,没有 CASE 语句
- 它还包括您的相关子查询作为附加 领域
- 然后外部查询可以将该字段嵌入到 CASE 语句中
SELECT
nested_query.ID,
nested_query.FULL_NAME,
nested_query.EarliestDate,
CASE
WHEN nested_query.EarliestDate BETWEEN TO_DATE('2000-01-01','YYYY-MM-DD') AND TO_DATE('2004-12-31','YYYY-MM-DD') THEN 'First Period'
WHEN nested_query.EarliestDate BETWEEN TO_DATE('2005-01-01','YYYY-MM-DD') AND TO_DATE('2009-12-31','YYYY-MM-DD') THEN 'Second Period'
WHEN nested_query.EarliestDate >= TO_DATE('2010-01-01','YYYY-MM-DD') THEN 'Third Period'
END AS CaseStatementResult
FROM
(
SELECT
APPLICANT.ID,
APPLICANT.FULL_NAME,
(
SELECT
MIN(PERSON_EVENTS_Sub.REQUESTED_DTE) /* Earliest date of the secondary event */
FROM
EVENTS PERSON_EVENTS_Sub
WHERE
PERSON_EVENTS_Sub.PER_ID = APPLICANT.ID /* Link the person ID */
AND PERSON_EVENTS_Sub.DEL_IND IS NULL /* Not a deleted event */
AND PERSON_EVENTS_Sub.EVTYPE_SDV_VALUE IN (/* List of secondary events */)
AND PERSON_EVENTS_Sub.COU_SDV_VALUE = PERSON_EVENTS.COU_SDV_VALUE /* Another link from the subQ to the main query */
AND PERSON_EVENTS_Sub.REQUESTED_DTE <= PERSON_EVENTS.REQUESTED_DTE /* subQ event occurred before main query event */
AND ROWNUM = 1 /* To ensure only one record returned, in case multiple rows match the MIN date */
)
AS EarliestDate
FROM
EVENTS PERSON_EVENTS,
PEOPLE APPLICANT
WHERE
PERSON_EVENTS.PER_ID=APPLICANT.ID
AND PERSON_EVENTS.EVTYPE_SDV_VALUE IN (/* List of values - removed ID information */)
AND PERSON_EVENTS.REQUESTED_DTE BETWEEN '01-Jan-2014' AND '31-Jan-2014'
) nested_query
关于sql - Oracle SQL : Re-use subquery for CASE WHEN without having to repeat subquery,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/35990568/
我是一名优秀的程序员,十分优秀!