MySQL - 根据 SELECT 多表查询编写更新查询
MySQL - Write an UPDATE Query based on SELECT Query on multiple tables
我在MySQL 或数据库方面还差得很远,所以我使用了一个名为FlySpeed SQL 查询的工具。该工具帮助我以图形方式创建 MySQL 查询。
这是我使用此工具创建的查询,并在 Internet 上进行了大量阅读。
Select
Employee.Firstname As Prénom,
Employee.Name As NOM,
TimeSheet.Filled As Validé,
TimeSheet.Closed As Clôturé,
Sum(Imputation.Hours) As `Somme des heures`,
TimeSheet.Month + 1 As Mois,
TimeSheet.Year As Année
From
Employee Inner Join
TimeSheet On TimeSheet.Employee_Id = Employee.Id Inner Join
Imputation On Imputation.TimeSheet_Id = TimeSheet.Id Inner Join
Project On Imputation.Project_Id = Project.Id
Where
TimeSheet.Filled = '1' And
(TimeSheet.Closed = '0' Or
TimeSheet.Closed Is Null) And
Imputation.Day <= Last_Day(Current_Date - Interval 1 Month) And Imputation.Day >= Date_Format(Current_Date - Interval 1 Month, '%Y-%m-01') And
Project.Id != '1'
Group By
Employee.Name, TimeSheet.Month + 1, TimeSheet.Year
Having
Sum(Imputation.Hours) >= 5 * ((DateDiff(Last_Day(Current_Date - Interval 1 Month), Date_Format(Current_Date - Interval 1 Month, '%Y-%m-01')) + 1))
Order By
Année,
Mois,
NOM
这个查询 returns 正是我想要的结果。保持与上述 MySQL 查询相同的条件,我想将 Closed 字段更新为“1”。我想做一些那里有味道的东西:
-- UPDATE Query
--
UPDATE TimeSheet
SET Closed = '1'
--
-- UPDATE Query
From
Employee Inner Join
TimeSheet On TimeSheet.Employee_Id = Employee.Id Inner Join
Imputation On Imputation.TimeSheet_Id = TimeSheet.Id Inner Join
Project On Imputation.Project_Id = Project.Id
--
-- With those conditions
--
Where
TimeSheet.Filled = '1' And
(TimeSheet.Closed = '0' Or
TimeSheet.Closed Is Null) And
-- Calculating a time range
Imputation.Day <= Last_Day(Current_Date - Interval 1 Month) And Imputation.Day >= Date_Format(Current_Date - Interval 1 Month, '%Y-%m-01')
And
Project.Id != '1'
Group By
Employee.Name, TimeSheet.Month + 1, TimeSheet.Year
Having
-- Calculation : >= 5 times the number of days in the period
Sum(Imputation.Hours) >= 5 * ((DateDiff(Last_Day(Current_Date - Interval 1 Month), Date_Format(Current_Date - Interval 1 Month, '%Y-%m-01')) + 1))
---
-- With those conditions
所以我需要帮助将我的 SELECT 查询转换为 UPDATE 查询。随时向我询问更多信息。
尝试在 joins
:
之后移动 set
操作
UPDATE TimeSheet Inner Join
Employee On TimeSheet.Employee_Id = Employee.Id Inner Join
Imputation On Imputation.TimeSheet_Id = TimeSheet.Id Inner Join
Project On Imputation.Project_Id = Project.Id
--
-- With those conditions
--
SET TimeSheet.Closed = '1'
Where
TimeSheet.Filled = '1' And
(TimeSheet.Closed = '0' Or
TimeSheet.Closed Is Null) And
-- Calculating a time range
Imputation.Day <= Last_Day(Current_Date - Interval 1 Month) And Imputation.Day >= Date_Format(Current_Date - Interval 1 Month, '%Y-%m-01')
And
Project.Id != '1'
Group By
Employee.Name, TimeSheet.Month + 1, TimeSheet.Year
Having
-- Calculation : >= 5 times the number of days in the period
Sum(Imputation.Hours) >= 5 * ((DateDiff(Last_Day(Current_Date - Interval 1 Month), Date_Format(Current_Date - Interval 1 Month, '%Y-%m-01')) + 1))
---
我终于找到了解决问题的方法。
这篇文章对我帮助很大:http://www.codeproject.com/Tips/831164/MySQL-can-t-specify-target-table-for-update-in-FRO
这里是:
UPDATE TimeSheet
SET
Closed = '1'
WHERE
TimeSheet.Id IN (SELECT
TimeSheet.Id
FROM
(SELECT
TimeSheet.Id
FROM
TimeSheet
Where
TimeSheet.Id IN (SELECT
TimeSheet.Id
FROM
Imputation
INNER JOIN TimeSheet ON Imputation.TimeSheet_Id = TimeSheet.Id
INNER JOIN Project ON Imputation.Project_Id = Project.Id
INNER JOIN Employee ON TimeSheet.Employee_Id = Employee.Id
Where
(TimeSheet.Closed = '0'
OR TimeSheet.Closed IS NULL)
AND TimeSheet.Filled = '1'
AND Imputation.Day <= Last_Day(Current_Date - INterval 1 Month)
AND Imputation.Day >= Date_Format(Current_Date - INterval 1 Month, '%Y-%m-01')
GROUP BY TimeSheet.Id
HAVING TimeSheet.Id NOT IN (SELECT DISTINCT
TimeSheet.Id
FROM
TimeSheet
INNER JOIN Imputation ON Imputation.TimeSheet_Id = TimeSheet.Id
INNER JOIN Project ON Imputation.Project_Id = Project.Id
INNER JOIN Employee ON TimeSheet.Employee_Id = Employee.Id
Where
Imputation.Day <= Last_Day(Current_Date - INterval 1 Month)
AND Imputation.Day >= Date_Format(Current_Date - INterval 1 Month, '%Y-%m-01')
AND Project.Id = '1')
AND Sum(Imputation.Hours) >= 5 * (DateDiff(Last_Day(Current_Date - INterval 1 Month), Date_Format(Current_Date - INterval 1 Month, '%Y-%m-01')) + 1))) VirtualTable01);
但是"solution"这个词可能有点强。我会说更多这是一种解决方法。所以我不确定这个请求是否优化得很好并且是否符合标准,但至少它具有给我想要的结果的优势。
与上面相同的查询,但注释为:
-- UPDATE Query
--
UPDATE TimeSheet
SET
Closed = '1'
--
-- UPDATE Query
--
-- With those conditions
--
WHERE
-- First Select
--
TimeSheet.Id IN (SELECT
TimeSheet.Id
FROM
-- Second Select
--
(SELECT
TimeSheet.Id
FROM
TimeSheet
Where
-- Third Select
--
TimeSheet.Id IN (SELECT
TimeSheet.Id
FROM
Imputation
INNER JOIN TimeSheet ON Imputation.TimeSheet_Id = TimeSheet.Id
INNER JOIN Project ON Imputation.Project_Id = Project.Id
INNER JOIN Employee ON TimeSheet.Employee_Id = Employee.Id
Where
(TimeSheet.Closed = '0'
OR TimeSheet.Closed IS NULL)
AND TimeSheet.Filled = '1'
AND Imputation.Day <= Last_Day(Current_Date - INterval 1 Month)
AND Imputation.Day >= Date_Format(Current_Date - INterval 1 Month, '%Y-%m-01')
GROUP BY TimeSheet.Id
-- Fourth Select
--
HAVING TimeSheet.Id NOT IN (SELECT DISTINCT
TimeSheet.Id
FROM
TimeSheet
INNER JOIN Imputation ON Imputation.TimeSheet_Id = TimeSheet.Id
INNER JOIN Project ON Imputation.Project_Id = Project.Id
INNER JOIN Employee ON TimeSheet.Employee_Id = Employee.Id
Where
Imputation.Day <= Last_Day(Current_Date - INterval 1 Month)
AND Imputation.Day >= Date_Format(Current_Date - INterval 1 Month, '%Y-%m-01')
AND Project.Id = '1')
--
-- End Fourth Select
AND Sum(Imputation.Hours) >= 5 * (DateDiff(Last_Day(Current_Date - INterval 1 Month), Date_Format(Current_Date - INterval 1 Month, '%Y-%m-01')) + 1))
--
-- End Third Select
) VirtualTable01)
--
-- End Second Select
--
-- End First Select
;
我在MySQL 或数据库方面还差得很远,所以我使用了一个名为FlySpeed SQL 查询的工具。该工具帮助我以图形方式创建 MySQL 查询。 这是我使用此工具创建的查询,并在 Internet 上进行了大量阅读。
Select
Employee.Firstname As Prénom,
Employee.Name As NOM,
TimeSheet.Filled As Validé,
TimeSheet.Closed As Clôturé,
Sum(Imputation.Hours) As `Somme des heures`,
TimeSheet.Month + 1 As Mois,
TimeSheet.Year As Année
From
Employee Inner Join
TimeSheet On TimeSheet.Employee_Id = Employee.Id Inner Join
Imputation On Imputation.TimeSheet_Id = TimeSheet.Id Inner Join
Project On Imputation.Project_Id = Project.Id
Where
TimeSheet.Filled = '1' And
(TimeSheet.Closed = '0' Or
TimeSheet.Closed Is Null) And
Imputation.Day <= Last_Day(Current_Date - Interval 1 Month) And Imputation.Day >= Date_Format(Current_Date - Interval 1 Month, '%Y-%m-01') And
Project.Id != '1'
Group By
Employee.Name, TimeSheet.Month + 1, TimeSheet.Year
Having
Sum(Imputation.Hours) >= 5 * ((DateDiff(Last_Day(Current_Date - Interval 1 Month), Date_Format(Current_Date - Interval 1 Month, '%Y-%m-01')) + 1))
Order By
Année,
Mois,
NOM
这个查询 returns 正是我想要的结果。保持与上述 MySQL 查询相同的条件,我想将 Closed 字段更新为“1”。我想做一些那里有味道的东西:
-- UPDATE Query
--
UPDATE TimeSheet
SET Closed = '1'
--
-- UPDATE Query
From
Employee Inner Join
TimeSheet On TimeSheet.Employee_Id = Employee.Id Inner Join
Imputation On Imputation.TimeSheet_Id = TimeSheet.Id Inner Join
Project On Imputation.Project_Id = Project.Id
--
-- With those conditions
--
Where
TimeSheet.Filled = '1' And
(TimeSheet.Closed = '0' Or
TimeSheet.Closed Is Null) And
-- Calculating a time range
Imputation.Day <= Last_Day(Current_Date - Interval 1 Month) And Imputation.Day >= Date_Format(Current_Date - Interval 1 Month, '%Y-%m-01')
And
Project.Id != '1'
Group By
Employee.Name, TimeSheet.Month + 1, TimeSheet.Year
Having
-- Calculation : >= 5 times the number of days in the period
Sum(Imputation.Hours) >= 5 * ((DateDiff(Last_Day(Current_Date - Interval 1 Month), Date_Format(Current_Date - Interval 1 Month, '%Y-%m-01')) + 1))
---
-- With those conditions
所以我需要帮助将我的 SELECT 查询转换为 UPDATE 查询。随时向我询问更多信息。
尝试在 joins
:
set
操作
UPDATE TimeSheet Inner Join
Employee On TimeSheet.Employee_Id = Employee.Id Inner Join
Imputation On Imputation.TimeSheet_Id = TimeSheet.Id Inner Join
Project On Imputation.Project_Id = Project.Id
--
-- With those conditions
--
SET TimeSheet.Closed = '1'
Where
TimeSheet.Filled = '1' And
(TimeSheet.Closed = '0' Or
TimeSheet.Closed Is Null) And
-- Calculating a time range
Imputation.Day <= Last_Day(Current_Date - Interval 1 Month) And Imputation.Day >= Date_Format(Current_Date - Interval 1 Month, '%Y-%m-01')
And
Project.Id != '1'
Group By
Employee.Name, TimeSheet.Month + 1, TimeSheet.Year
Having
-- Calculation : >= 5 times the number of days in the period
Sum(Imputation.Hours) >= 5 * ((DateDiff(Last_Day(Current_Date - Interval 1 Month), Date_Format(Current_Date - Interval 1 Month, '%Y-%m-01')) + 1))
---
我终于找到了解决问题的方法。
这篇文章对我帮助很大:http://www.codeproject.com/Tips/831164/MySQL-can-t-specify-target-table-for-update-in-FRO
这里是:
UPDATE TimeSheet
SET
Closed = '1'
WHERE
TimeSheet.Id IN (SELECT
TimeSheet.Id
FROM
(SELECT
TimeSheet.Id
FROM
TimeSheet
Where
TimeSheet.Id IN (SELECT
TimeSheet.Id
FROM
Imputation
INNER JOIN TimeSheet ON Imputation.TimeSheet_Id = TimeSheet.Id
INNER JOIN Project ON Imputation.Project_Id = Project.Id
INNER JOIN Employee ON TimeSheet.Employee_Id = Employee.Id
Where
(TimeSheet.Closed = '0'
OR TimeSheet.Closed IS NULL)
AND TimeSheet.Filled = '1'
AND Imputation.Day <= Last_Day(Current_Date - INterval 1 Month)
AND Imputation.Day >= Date_Format(Current_Date - INterval 1 Month, '%Y-%m-01')
GROUP BY TimeSheet.Id
HAVING TimeSheet.Id NOT IN (SELECT DISTINCT
TimeSheet.Id
FROM
TimeSheet
INNER JOIN Imputation ON Imputation.TimeSheet_Id = TimeSheet.Id
INNER JOIN Project ON Imputation.Project_Id = Project.Id
INNER JOIN Employee ON TimeSheet.Employee_Id = Employee.Id
Where
Imputation.Day <= Last_Day(Current_Date - INterval 1 Month)
AND Imputation.Day >= Date_Format(Current_Date - INterval 1 Month, '%Y-%m-01')
AND Project.Id = '1')
AND Sum(Imputation.Hours) >= 5 * (DateDiff(Last_Day(Current_Date - INterval 1 Month), Date_Format(Current_Date - INterval 1 Month, '%Y-%m-01')) + 1))) VirtualTable01);
但是"solution"这个词可能有点强。我会说更多这是一种解决方法。所以我不确定这个请求是否优化得很好并且是否符合标准,但至少它具有给我想要的结果的优势。
与上面相同的查询,但注释为:
-- UPDATE Query
--
UPDATE TimeSheet
SET
Closed = '1'
--
-- UPDATE Query
--
-- With those conditions
--
WHERE
-- First Select
--
TimeSheet.Id IN (SELECT
TimeSheet.Id
FROM
-- Second Select
--
(SELECT
TimeSheet.Id
FROM
TimeSheet
Where
-- Third Select
--
TimeSheet.Id IN (SELECT
TimeSheet.Id
FROM
Imputation
INNER JOIN TimeSheet ON Imputation.TimeSheet_Id = TimeSheet.Id
INNER JOIN Project ON Imputation.Project_Id = Project.Id
INNER JOIN Employee ON TimeSheet.Employee_Id = Employee.Id
Where
(TimeSheet.Closed = '0'
OR TimeSheet.Closed IS NULL)
AND TimeSheet.Filled = '1'
AND Imputation.Day <= Last_Day(Current_Date - INterval 1 Month)
AND Imputation.Day >= Date_Format(Current_Date - INterval 1 Month, '%Y-%m-01')
GROUP BY TimeSheet.Id
-- Fourth Select
--
HAVING TimeSheet.Id NOT IN (SELECT DISTINCT
TimeSheet.Id
FROM
TimeSheet
INNER JOIN Imputation ON Imputation.TimeSheet_Id = TimeSheet.Id
INNER JOIN Project ON Imputation.Project_Id = Project.Id
INNER JOIN Employee ON TimeSheet.Employee_Id = Employee.Id
Where
Imputation.Day <= Last_Day(Current_Date - INterval 1 Month)
AND Imputation.Day >= Date_Format(Current_Date - INterval 1 Month, '%Y-%m-01')
AND Project.Id = '1')
--
-- End Fourth Select
AND Sum(Imputation.Hours) >= 5 * (DateDiff(Last_Day(Current_Date - INterval 1 Month), Date_Format(Current_Date - INterval 1 Month, '%Y-%m-01')) + 1))
--
-- End Third Select
) VirtualTable01)
--
-- End Second Select
--
-- End First Select
;