2016-10-24 19 views
0

私は2つのテーブルEmployeesとEmployeeVacationsを持っています。私は各従業員がどれだけ多くの休暇を取ったかと現在の現在の残高の合計を取得するためにSQLクエリを実行しようとしています。私の現在のSQLクエリは次のとおりです。合計でSQLクエリ内のSQLクエリ

SELECT 
    e.PIN, 
    e.FirstName, 
    e.LastName, 
    e.Uniform, 
    e.AL_Cap, 
    ev.Value AS '10/1 Balance', 
    (SELECT 
     SUM(value) 
    FROM EmployeeVacations 
    WHERE CreationDate >= '2016-10-01' 
    AND Vacation_Type = 'Taken' 
    AND Vacation_Kind = 'AL' 
    AND EmployeeId = 13) 
    AS Taken 
FROM employees e, 
     EmployeeVacations ev 
WHERE e.Id = ev.EmployeeId 
AND ev.IsHistory = 0 
AND ev.Vacation_Type = 'Forward' 
AND ev.Vacation_Kind = 'AL' 
AND EmployeeId = 13 
ORDER BY e.LastName, e.FirstName 

これは私が1人の従業員を選んだ場合に機能します。 「EmployeeId = 13」の場所を削除すると、すべての従業員のリストがすべての行の合計休暇の合計(1300時間など)で取得されます。どのように私はそれを打ち破ることができますので、Takenは各従業員専用です。

+0

これは、使用しているSQL Serverのバージョンによっては、ウィンドウ関数を使用して処理する可能性があります。 – SQLUser44

+3

明示的な結合を使用する必要があります。これははるかに読みやすいです。 – scsimon

+0

従業員の前払いレコードのリストを、従業員の合計額と共に表示しています。これが望ましいですか?あるいは、従業員の前払いの合計、つまり従業員一人につき結果の行が1つだけであることを望みますか? –

答えて

1

EmployeeIdあたりEmployeeVacationsを集約クエリです:

select 
    e.pin, 
    e.firstname, 
    e.lastname, 
    e.uniform, 
    e.al_cap, 
    ev.forward_sum as "10/1 balance", 
    ev.taken_sum as taken 
from employee e 
left join 
(
    select  
    employeeid, 
    sum(case when vacation_type = 'Forward' 
      and ishistory = 0 then value else 0 end) as forward_sum, 
    sum(case when vacation_type = 'Taken' 
      and creationdate >= '20161001' then value else 0 end) as taken_sum, 
    from employeevacations 
    where vacation_kind = 'AL' 
    group by employeeid 
) ev on ev.employeeid = e.employeeid 
order by e.lastname, e.firstname; 

ください...

  • 使用明示的な結合ではなく、エラーを起こしにくいために、1992年以前のカンマ区切りの結合ではなく読みやすくなりました。
  • エイリアス名には二重引用符を使用します。一重引用符は文字列リテラルのためのものです。
  • 日付に「yyyymmdd」を使用します。これは、SQL Serverでサポートされている日付リテラル形式です。
+0

私はこのソリューションが気に入っています。 – RickCJ7

+0

どのようにev.turn_sumをev.forward_sumから新しい列に引くのですか?私は試しました 合計(ev.forward_sum - ev.taken_sum)は "10/24バランス" として私がエラーでグループを与えています。ありがとう! – RickCJ7

+0

ev.forward_sumから 'ev.taken_sum'を引く方法は?まあ、マイナス記号のついたコースは 'ev.forward_sum-ev.taken_sum'です。あなたの追加の 'sum'は単に意味をなさない。 –

2

サブクエリが "親"クエリの値を使用するコアクエリが必要です。

SELECT e.PIN ... 
    (select SUM(value) .... WHERE EmployeeID = e.id) as taken 
               ^^^^^ 

内側問合せは、親クエリの行ごとに一度実行されなければならないので、これらは、非常に非効率的であることができることに留意されたいです。多くの場合、通常のJOINのクエリを適切なグループにして書き直すほうがよいでしょう。ただ、ここでは...あなたもなく、1つの前方レコードよりも合計を望むかもしれないと推測

+0

Macの最後の段落を強調する。 99%の確率で、これはより効率的に書くことができます。 – scsimon

+0

セマンティック的に同じクエリのために全く異なる実行計画が出てきたら、それは非常に悪いオプティマイザになります。 –

+0

私はJoinsを使用しているSQLの専門家ではないので、Marcの提案が働きました。ありがとう、マーク! – RickCJ7