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
;