0

我有一个 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 比较陌生,有人可以解释发生了什么吗?谢谢!

4

3 回答 3

5

由于您使用的是 sql server,因此我的建议是通过 and 来实现和row_number()分区。这将进入子查询,然后您应用过滤器以仅返回行号等于一个或最新记录的那些:ProductDescriptionCourseDescription

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
于 2012-12-04T21:03:13.533 回答
3

它的这条线

HAVING MIN(a.DateTaken)

应该是布尔类型,例如

  HAVING MIN(a.DateTaken) > GETUTCDATE()

必须返回 True 或 False(布尔值)

于 2012-12-03T17:54:00.457 回答
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'
于 2012-12-05T16:55:23.713 回答