Selectați coloane specifice din două tabele

Să presupunem că am două tabele tblEmployee și tblEmpSalary . Trebuie să scriu o declarație SQL pentru a obține o listă a tuturor angajaților, numele și salariile lor, care primesc cel mai mare salariu în fiecare departament.

Datele din tabelul de probă sunt aici:

enter image description here

0

4 răspunsuri

SELECT   a.d, a.m, b.strEmpName 
FROM     (
          SELECT    strDepartment d, MAX(monSalary) m 
          FROM      (
                     SELECT    * 
                     FROM      tblEmployee e 
                     LEFT JOIN tblEmpSalary s ON e.inEmployeeID = s.intEmployeeID
                    ) 
           GROUP BY strDepartment
          ) a 
LEFT JOIN (
           SELECT    * 
           FROM      tblEmployee e 
           LEFT JOIN tblEmpSalary s ON e.inEmployeeID = s.intEmployeeID
          ) b ON a.d=b.strDepartment AND a.m=b.M
0
adăugat
Apreciate, nawfal:>
adăugat autor Andrius Naruševičius, sursa

În acest caz, puteți utiliza funcțiile de rang:

WITH ranked AS (
  SELECT
    e.*,
    s.monSalary,
    rnk = RANK() OVER (PARTITION BY e.strDepartment ORDER BY s.monSalary DESC)
  FROM tblEmplopyee e
  INNER JOIN tblEmpSalary s ON e.intEmployeeID = s.intEmployeeID
)
SELECT
  intEmploeeID,
  strEmpName,
  strDepartment,
  monSalary
FROM ranked
WHERE rnk = 1

Funcția RANK() va face dacă aveți nevoie doar de cei care au cel mai mare salariu. Cu RANK() , interogarea poate reveni mai mult decât angajatul pe departament dacă are același salariu.

Alternativ, puteți folosi DENSE_RANK() în loc de RANK() , cu același efect, dar DENSE_RANK() angajații cu salariile de top n . (Ați putea să specificați că în condiția WHERE astfel:

WHERE rnk <= n

)

Dacă, totuși, aveți nevoie de exact un angajat pe departament, chiar dacă mai multe dintre ele corespund cerinței, folosiți ROW_NUMBER() <// code>. Dar probabil că va trebui să adăugați un alt criteriu la clauza ORDER BY a funcției de clasificare, de ex. asa:

... ORDER BY s.monSalary DESC, e.strEmpName ASC)

De fapt, ROW_NUMBER() ar face pur și simplu interogarea dvs. orientată către angajați, mai degrabă decât orientată spre salarii. Cu ROW_NUMBER() , veți putea să returnați interogarea n cea mai plătită angajați aceeași condiție ca și cu DENSE_RANK() :

WHERE rnk <= n

Puteți citi mai multe despre funcțiile de rang în SQL Server pe MSDN:

0
adăugat
+1 Prefer această soluție, deoarece este mai ușor să adăugați mai multe câmpuri fie pentru criteriile de clasificare, fie pentru grupare (În acest exemplu, acestea pot avea subdiviziuni.
adăugat autor JeffO, sursa
SELECT tblEmployee.strEmpName, max_salaries.strDepartment, max_salaries.salary
FROM (SELECT tblEmployee.strDepartment, MAX(monSalary) 
      FROM tblEmployee INNER JOIN tblEmpSalary 
           ON tblEmployee.intEmployeeID = tblEmpSalary.intEmployeeID
      GROUP BY tblEmployee.strDepartment) max_salaries
INNER JOIN tblEmployee ON tblEmployee.strDepartment = max_salaries.strDepartment
INNER JOIN tblEmpSalary ON tblEmpSalary.monSalary = max_salaries.salary
           AND tblEmpSalary.intEmployeeID = tblEmployee.intEmployeeID

În cazul a doi sau mai mulți angajați cu salarii egale maxime - aceasta va reveni tuturor pentru departamentul specificat.

0
adăugat
SELECT e.strEmpName, s.monSalary
FROM tblEmployee e
JOIN tblEmpSalary s ON e.intEmployeeID = s.intEmployeeID
WHERE e.strDepartment + '-' + CAST(s.monSalary AS varchar(20)) IN (
     SELECT e2.strDepartment + '-' + CAST(MAX(s2.monSalary) AS varchar(20))
     FROM tblEmployee e2
     JOIN tblEmpSalary s2 ON e2.intEmployeeID = s2.intEmployeeID
     GROUP BY e2.strDepartment)

Avertisment: Nu pot testa această interogare chiar acum, deci ar putea avea unele detalii minore greșite.

0
adăugat
Bună @Pablo este sunet bun, dar printr-o eroare cum ar fi "conversie a eșuat atunci când convertirea valorii varchar" c + + - "la tipul de date int'.Nu există nici un departament id, aici este doar numele departamentului.
adăugat autor yeasir007, sursa
@ yeasir007 OK, am schimbat interogarea un pic, eu thik că ar trebui să repare.
adăugat autor Pablo, sursa