【问题标题】:MySQL - Write an UPDATE Query based on SELECT Query on multiple tablesMySQL - 根据多个表上的 SELECT Query 编写 UPDATE Query
【发布时间】:2015-02-11 15:40:42
【问题描述】:

我在 MySQL 或数据库方面还远远不够,所以我使用了一个名为 FlySpeed SQL Query 的工具。这个工具帮助我以图形方式创建 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

这个查询准确地返回了我想要的结果。保持与上面的 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 查询。请随时向我询问更多信息。

【问题讨论】:

  • 它不起作用?假设您要更新返回的每条记录,乍一看似乎还可以。
  • 当我按照我的想法尝试查询时:ERROR 1064 (42000): You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'From Employee Inner Join TimeSheet On TimeSheet.Employee_Id = Employee.Id Inner ' at line 3(在使用之前我已取消注释此处发布的查询。)

标签: mysql sql sql-update mysql-error-1064


【解决方案1】:

尝试将set 操作移到joins 之后:

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))
    ---

【讨论】:

  • 当我尝试您的查询@sgeddes 时:ERROR 1064 (42000): You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'Group By Employee.Name, TimeSheet.Month + 1, TimeSheet.Year Having Sum(I' at line 13 所以,您的提议@sgeddes 似乎比我的更有吸引力。该查询仅在第 13 行“Group By”处阻塞。 (在使用之前,我已取消注释此处发布的查询。)
【解决方案2】:

我终于找到了解决问题的方法。

这篇文章对我帮助很大: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);

但是,“解决方案”这个词可能有点强。我会说更多,这是一种解决方法。所以我不确定这个请求是否得到了很好的优化,它是否符合标准,但至少它有优势,可以给我想要的结果。

与上述相同的查询,但已注释:

-- 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
;

【讨论】:

    猜你喜欢
    • 2020-04-04
    • 2020-06-16
    • 1970-01-01
    • 2020-10-27
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-05-28
    相关资源
    最近更新 更多