我一直在尝试获取一个查询,根据给定的条件(如果isCurrent = 1或者不是),我应该根据CurriculumId /这将是一个存储过程的参数给我一个值/行。 如果isCurrent = 1,该值应返回给我具有最新StartDate的项目,但如果isCurrent = 0则应该给我一个具有最新EndDate的项目。
问题是我每个CurriculumId只需要一个项目,理想情况是isCurrent = 1和最新的StartDate(忽略剩余的行)但是,如果没有isCurrent = 1的经验,那么它应该返回到我是最新EndDate的那个。
我以前的查询几乎正常工作,但是当我想要检索一个或另一个时,我仍然得到具有最新StartDate(isCurrent = 1)的那个和具有最新EndDate的那个。
我来看看下面的问题:
SELECT table.IntProfessionalExperienceId,
table.IsCurrent,
table.StartDate,
table.EndDate
FROM table
WHERE table.CurriculumId = 12
AND
CASE table.IsCurrent
WHEN 1
THEN
table.StartDate = (
SELECT max(table.StartDate)
FROM table
WHERE table.IsCurrent = 1
AND table.CurriculumId = 12
GROUP BY table.CurriculumId
)
ELSE
table.EndDate = (
SELECT max(table.EndDate)
FROM table
WHERE table.CurriculumId = 12
GROUP BY table.CurriculumId
)
END
单独地,查询似乎正常工作并返回假设的值,尽管当作为一个整体运行时我得到以下错误:
Msg 102, Level 15, State 1, Line 8
Incorrect syntax near '='.
Msg 102, Level 15, State 1, Line 14
Incorrect syntax near ')'.
Msg 102, Level 15, State 1, Line 21
Incorrect syntax near ')'.
我的语法错误是什么?我知道通过阅读错误查询有什么问题,但我只是不知道如何解决它。它只是语法还是我开始时查询错误?
答案 0 :(得分:3)
将其拆分为多个条件,如下所示:
SELECT
table.IntProfessionalExperienceId,
table.IsCurrent,
table.StartDate,
table.EndDate
FROM table
WHERE
table.CurriculumId = 12 AND
(
(
Table.IsCurrent = 1 AND
table.StartDate =
(
SELECT max(table.StartDate)
FROM table
WHERE
table.IsCurrent = 1 AND
table.CurriculumId = 12
GROUP BY table.CurriculumId
)
) OR
(
ISNULL(table.IsCurrent,0) != 1 AND
table.EndDate =
(
SELECT max(table.EndDate)
FROM table
WHERE table.CurriculumId = 12
GROUP BY table.CurriculumId
)
)
)
编辑:另一种可以说更简单的方法是在WHERE子句中预先聚合所需的数据,这样你只需要一次调用它,而不是分别评估每一行。如下所示:
SELECT
table.IntProfessionalExperienceId,
table.IsCurrent,
table.StartDate,
table.EndDate
FROM
table
INNER JOIN
(
SELECT
MAX(table.EndDate) AS MaxEndDate,
MAX(CASE WHEN table.IsCurrent = 1 THEN table.StartDate END) AS MaxCurrentStartDate
FROM table
WHERE CurriculumID = 12
) MaxDates ON
(Table.IsCurrent = 1 AND Table.StartDate = MaxDates.MaxCurrentStartDate) OR
(ISNULL(Table.IsCurrent, 0) != 1 AND Table.EndDate = MaxDates.MaxEndDate)
WHERE
table.CurriculumId = 12
答案 1 :(得分:2)
使用带有适当order by子句的ROW_NUMBER为每个行在其Curriculumid组中添加一个等级。然后只取出排名为1的记录(即最佳匹配)。
select
intprofessionalexperienceid,
iscurrent,
startdate,
enddate
from
(
select mytable.*
row_number() over
(
partition by curriculumid
order by
case when iscurrent = 1 then 1 else 2 end,
case when iscurrent = 1 then startdate else enddate end desc
) as rn
from mytable
) ranked
where rn = 1;
(我知道这实际上并没有回答你的问题,但在我看来,这是解决问题的直接方法。)
答案 2 :(得分:1)
尝试以这种方式使用CASE
州议员:
SELECT table.IntProfessionalExperienceId,
table.IsCurrent,
table.StartDate,
table.EndDate
FROM table
WHERE table.CurriculumId = 12
AND table.EndDate = CASE
WHEN table.IsCurrent = 1
THEN (
SELECT max(table.StartDate)
FROM table
WHERE table.IsCurrent = 1
AND table.CurriculumId = 12
GROUP BY table.CurriculumId
)
ELSE
(
SELECT max(table.EndDate)
FROM table
WHERE table.CurriculumId = 12
GROUP BY table.CurriculumId
)
END