我有一个T-SQL查询,旨在清除某个产品培训的重复条目,只获取具有最新DateTaken的条目。例如,如果某人已经参加了3次特定的培训课程,我们只想显示一行,该行是包含最新DateTaken的行。这是我到目前为止,但是我收到以下错误:
在“ORDER”附近的预期条件的上下文中指定的非布尔类型的表达式。
ORDER BY是必要的,因为我们希望在截止日期之前将此查询的所有结果分组。以下是完整查询:
SELECT DISTINCT
p.ProductDescription as ProductDesc,
c.CourseDescription as CourseDesc,
c.Partner, a.DateTaken, a.DateExpired, p.Status
FROM
sNumberToAgentId u, AgentProductTraining a, Course c, Product p
WHERE
@agentId = u.AgentId
and u.sNumber = a.sNumber
and a.CourseCode = c.CourseCode
and (a.DateExpired >= @date or a.DateExpired IS NULL)
and a.ProductCode = p.ProductCode
and (p.status != 'D' or p.status IS NULL)
GROUP BY
(p.ProductDescription)
HAVING
MIN(a.DateTaken)
ORDER BY
DateExpired ASC
修改
我对GROUP BY和HAVING子句进行了以下更改,但是我仍然收到错误:
GROUP BY
(p.ProductDescription, c.CourseDescription)
HAVING
MIN(a.DateTaken) > GETUTCDATE()
在SQL Management Studio中,红线错误标记出现在p.ProductDescription之后的','之后,c.CourseDescription之后的')',a.DateTaken中的'a'和右括号')' GETUTCDATE()。如果我只是将GROUP BY语句保留为仅包含p.ProductDescription,则会收到以下错误消息:
列'Product.ProductDescription'在选择列表中无效,因为它不包含在聚合函数或GROUP BY子句中。
我对SQL比较陌生,有人可以解释发生了什么吗?谢谢!
答案 0 :(得分:5)
我建议你使用sql server是为了实现row_number()
并按ProductDescription
和CourseDescription
进行分区。这将进入子查询,然后应用过滤器仅返回行号等于1或最近记录的那些:
select *
from
(
SELECT p.ProductDescription as ProductDesc,
c.CourseDescription as CourseDesc,
c.Partner, a.DateTaken, a.DateExpired, p.Status
row_number() over(partition by p.ProductDescription, c.CourseDescription order by a.DateTaken desc) rn
FROM sNumberToAgentId u
INNER JOIN AgentProductTraining a
ON u.sNumber = a.sNumber
AND (a.DateExpired >= @date or a.DateExpired IS NULL)
INNER JOIN Course c
ON a.CourseCode = c.CourseCode
INNER JOIN Product p
ON a.ProductCode = p.ProductCode
AND (p.status != 'D' or p.status IS NULL)
WHERE u.AgentId = @agentId
) src
where rn = 1
order by DateExpired
答案 1 :(得分:3)
这一行
HAVING MIN(a.DateTaken)
应该是布尔类型,例如
HAVING MIN(a.DateTaken) > GETUTCDATE()
必须返回True或False(布尔值)
答案 2 :(得分:0)
这是我最后使用的查询。它类似于上面的建议:
SELECT ProductDesc, CourseDesc, Partner, DateTaken, DateExpired, Status
FROM(
SELECT
p.ProductDescription as ProductDesc,
c.CourseDescription as CourseDesc,
c.Partner, a.DateTaken, a.DateExpired, p.Status,
row_number() OVER (PARTITION BY p.ProductDescription, c.CourseDescription ORDER BY abs(datediff(dd, DateTaken, GETDATE()))) as Ranking
FROM
sNumberToAgentId u, AgentProductTraining a, Course c, Product p
WHERE
@agentId = u.AgentId
and u.sNumber = a.sNumber
and a.CourseCode = c.CourseCode
and (a.DateExpired >= @date or a.DateExpired IS NULL)
and a.ProductCode = p.ProductCode
and (p.status != 'D' or p.status IS NULL)
) aa
WHERE Ranking = '1'