2017-09-22 20 views
0

次のコードのSELECTステートメントに集計サブクエリを追加しようとしています。条件照会親クエリのSQL Server集計サブクエリエラー

DECLARE @Date1 Date 
DECLARE @Date2 Date 

SET @Date1 = '2017-01-01' 
SET @Date2 = '2017-03-01' 

SELECT 
    p.PracticeName [Practice Name], 
    dbo.getFormattedName(l.Userid) [User Name], 
    MAX(EventDate) [Last Activity], 
    COUNT(*) [Activity Count], 
    (SELECT COUNT(*) 
    FROM UserEvent EVT (NOLOCK) 
    WHERE EVT.EventTypeID = 1 
     AND EVT.UserID = au.userID 
     AND EVT.EventDate >= @Date1 
     AND EVT.EventDate <= DATEADD(DAY, 1, @Date2) 
    GROUP BY 
     au.userID) [Login Count] 
FROM  
    dbo.AudLog l (NOLOCK) 
JOIN 
    Appuser au (NOLOCK) ON l.UserID = au.UserID 
JOIN 
    Practice p (NOLOCK) ON au.PracticeID = p.PracticeID 
WHERE 
    l.EnvironmentID = 1 
    AND EventDate >= @Date1 
    AND EventDate <= DATEADD(DAY,1,@Date2) 
GROUP BY  
    p.PracticeName, 
    dbo.getFormattedName(l.Userid) 
ORDER BY  
    p.PracticeName, 
    dbo.getFormattedName(l.Userid) 

私は次のエラーを取得しています:

Column 'Appuser.UserID' is invalid in the select list because it is not contained in either an aggregate function or the GROUP BY clause.

私は同じように使用しています、AppUser.UserIDを選択していないよので、そのエラーが私のサブクエリに適用される理由を私は理解していませんサブクエリを親クエリと整列させるための条件の参照。また、実際にはサブクエリ内のGROUP BYステートメントにあります。

私はthis questionを参照しましたが、説明に基づいて私のクエリは機能していると思います。

助けてください。

+0

わずかなトピックから逸​​脱しているが、あなたが本当に読む必要がある記事...のhttp://blogs.sqlsentry.com/aaronbertrand/bad-habits-nolock-everywhere/ –

答えて

0

GROUP BYを必要とする外部クエリに集計関数がないため、参照している質問が異なります。

相関サブクエリを所有者(EVT.UserID = au.userID)として使用すると、外側のクエリ列の参照は、この場合はau.userIDになります(サブクエリに必要であるため、外側の選択の列の一部になりました)。

単純な修正は、外部グループにau.userID列を追加することです。

+0

私はあなたが何を意味するかを見ます。私はあなたの提案を最初に試みたが、 "各GROUP BY式には外部参照ではない少なくとも1つの列が含まれていなければならない"というエラーが返されました。私は、サブクエリのau.UserIDをevt.UserIDに置き換え、それは魅力的に機能しました。ありがとうございます –

+0

@ W.Harrおっと、私はあなたがサブクエリのグループ化にあったものを見落としました。良いキャッチと喜んでそれはあなたのために働いた。 –

0

フィールドに結合すると、結合の一部である中間データセットに存在します。選択リストに含まれていなくても、リストの一部として考慮する必要があります。

本当に問題ではないと思われる場合は、group by節に追加して、依然として必要な結果を得ることができます。

0

エラーは、あなたのサブクエリを参照していません。

メインクエリのselect句の次の行dbo.ch_getFormattedProviderName(l.Userid)が問題です。

selectステートメントで関数呼び出しdbo.ch_getFormattedProviderName(l.Userid)を使用していますが、group by句の異なる関数dbo.getFormattedName(l.Userid)でグループ化しています。 dbo.getFormattedNameまたはその逆に

変更機能dbo.ch_getFormattedProviderName

+0

は私が持っていた、このことを気付いてくれてありがとうここにそれを掲示する前に、いくつかのマイナーチェンジを行いました。あなたが言いました調整をしました –

0

ご質問にはお答えできませんが、あなたの質問に言及したいことがいくつかあります。

  • スカラー関数を使用しないでください。それらをまったく使用しないでください。彼らはそれらの使い方の良い例はほとんどありません。ロジックをカプセル化したい場合は、代わりにテーブル値関数を使用してください。スカラ関数は、特にそれらをフィルタリングする必要がある場合、パフォーマンスを低下させるものです。それらは索引付けされず、1行ごとに実行されます。
  • 個人的には、このようなインラインサブクエリが通常のJOINインラインクエリより優れているという状況はありませんでした。しかし、パフォーマンスが悪かった時には、多くの逆の状況がありました。 JOIN(SELECT ...)
  • NOLOCKsを使用して、いつでもそのようなクエリを書き直すことができます。あなたがロック問題を抱えているなら、インデックス/再設計技術を使ってそれらを解決する。回避策を講じるのではなく、問題の根本を解決する方がよいでしょう。