0

特定の製品トレーニングの重複エントリを取り除き、最新のDateTakenを持つエントリのみを取得するように設計されたT-SQLクエリがあります。たとえば、誰かが特定のトレーニングコースを3回受講した場合、1つの行のみを表示します。その行は、最新のDateTakenを含む行です。これが私がこれまでに持っているものです、しかし私は次のエラーを受け取ります:

'ORDER'の近くで、条件が予期されるコンテキストで指定された非ブール型の式。

このクエリのすべての結果を有効期限でグループ化するため、ORDERBYが必要です。以下は完全なクエリです:

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を使用しているので、とを使用して実装およびパーティション化することをお勧めしrow_number()ます。これはサブクエリに入り、次にフィルタを適用して、行番号が1つまたは最新のレコードと等しいものだけを返します。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 に答える