SELECT employees$.emp_no, employees$.first_name, employees$.last_name, salaries$.salary, departments$.dept_name
FROM employees$, dept_emp$, departments$, salaries$
WHERE employees$.emp_no = dept_emp$.emp_no AND
dept_emp$.dept_no = departments$.dept_no AND
employees$.emp_no = salaries$.emp_no;
我也試過
SELECT employees$.emp_no, employees$.first_name, employees$.last_name, salaries$.salary, dept_emp$.dept_no, departments$.dept_name
FROM employees$
join dept_emp$
on employees$.emp_no = dept_emp$.emp_no
join salaries$
on employees$.emp_no = dept_emp$.emp_no
join departments$
on dept_emp$.dept_no = departments$.dept_no
我應該有 400 行,第一個查詢輸出 16000,第二個查詢輸出 442。我不確定出了什么問題,我已經堅持了好幾天了。我假設我必須加入 4 個表并從那里執行 > 查詢。我還沒有進入第二部分,因為我的加入有問題。我將不勝感激任何幫助,下面發布的完整問題。(發布后意識到我可能也需要 dept_manager 表,任何人都可以通過發布完整的解決方案來提供幫助,將不勝感激,謝謝)
完整問題:“列出工資超過經理工資的所有員工。”
ERD



uj5u.com熱心網友回復:
由于您的許多表將有每個員工具有不同有效期間的多條記錄(from_date- to_date,您需要將這些記錄過濾到相關期間,根據您的問題是今天,因此要獲得有效工資,您可以使用以下內容:
SELECT *
FROM salaries$ AS s
WHERE s.from_date <= CURRENT_TIMESTAMP
AND (s.to_date > CURRENT_TIMESTAMP OR s.to_date IS NULL);
您還需要對dept_emp和應用相同的邏輯dept_manager。
順便說一句,SQL Server 的臨時表是一種很好的管理方式,它使主表中只有一條記錄,因此您無需擔心這些過濾器,但您也可以在以下位置查詢歷史資料一個給定的時間點很容易,例如SELECT * FROM Salaries FOR SYSTEM_TIME AS OF '20220201'。感謝這是一個家庭作業問題,所以現在這些都無關緊要,但將來可能會有用。
所以,回到原來的點,您需要將這些過濾器添加到您的查詢中,您可以這樣做:
SELECT e.emp_no, e.first_name, e.last_name, s.salary, d.dept_no, d.dept_name
FROM employees$ AS e
JOIN dept_emp$ AS de
ON de.emp_no = e.emp_no
AND de.from_date <= CURRENT_TIMESTAMP
AND (de.to_date > CURRENT_TIMESTAMP OR de.to_date IS NULL)
JOIN salaries$ AS s
ON s.emp_no = e.emp_no
AND s.from_date <= CURRENT_TIMESTAMP
AND (s.to_date > CURRENT_TIMESTAMP OR s.to_date IS NULL)
JOIN departments$ AS d
ON d.dept_no = de.dept_no;
*注意我在這里使用了別名,因為這(在我看來)使查詢更容易讀寫
以上內容應涵蓋您獲得所有員工及其薪水的基本方案。然后,您只需要再加入幾次即可獲得經理的薪水,然后您可以應用過濾器來檢查薪水高于經理的員工:
SELECT e.emp_no, e.first_name, e.last_name, s.salary, d.dept_no, d.dept_name
FROM employees$ AS e
JOIN dept_emp$ AS de
ON de.emp_no = e.emp_no
AND de.from_date <= CURRENT_TIMESTAMP
AND (de.to_date > CURRENT_TIMESTAMP OR de.to_date IS NULL)
JOIN salaries$ AS s
ON s.emp_no = e.emp_no
AND s.from_date <= CURRENT_TIMESTAMP
AND (s.to_date > CURRENT_TIMESTAMP OR s.to_date IS NULL)
JOIN departments$ AS d
ON d.dept_no = de.dept_no
JOIN dept_manager$ AS dm
ON dm.dept_no = d.dept_no
AND dm.from_date <= CURRENT_TIMESTAMP
AND (dm.to_date > CURRENT_TIMESTAMP OR dm.to_date IS NULL)
JOIN salaries$ AS ms -- Manager Salary
ON ms.emp_no = dm.emp_no
AND ms.from_date <= CURRENT_TIMESTAMP
AND (ms.to_date > CURRENT_TIMESTAMP OR ms.to_date IS NULL)
WHERE s.salary > ms.salary;
如果這是我的資料庫,我會傾向于創建一個函式來獲取特定日期的活動記錄,例如
CREATE FUNCTION dbo.SalariesAsOf(@Date DATE)
RETURNS TABLE
AS
RETURN
( SELECT emp_no, salary
FROM Salaries$
WHERE s.from_date <= @Date
AND (s.to_date > @Date OR s.to_date IS NULL)
);
并對所有具有這種性質的表重復此操作,它封裝了此邏輯并使其更易于重用。這會將最終查詢更改為:
SELECT e.emp_no, e.first_name, e.last_name, s.salary, d.dept_no, d.dept_name
FROM employees$ AS e
JOIN dbo.DeptEmpAsOf(CURRENT_TIMESTAMP) AS de
ON de.emp_no = e.emp_no
JOIN dbo.SalariesAsOf(CURRENT_TIMESTAMP) AS s
ON s.emp_no = e.emp_no
JOIN departments$ AS d
ON d.dept_no = de.dept_no
JOIN dbo.DeptManagerAsOf(CURRENT_TIMESTAMP) AS dm
ON dm.dept_no = d.dept_no
JOIN dbo.SalariesAsOf(CURRENT_TIMESTAMP) AS ms -- Manager Salary
ON ms.emp_no = dm.emp_no
WHERE s.salary > ms.salary;
同樣,我認為這可能超出了實際作業問題的范圍,但這是我會做的,所以我想我會把我的 2p 價值添加到問題的末尾。
轉載請註明出處,本文鏈接:https://www.uj5u.com/qiye/431104.html
上一篇:SQL-合并兩個查詢
