我希望更新一个列,当另一个表中的select不为空时,使用另一个表中的选定日期以及当它为空且具有常数日期时。
我的桌子:
CREATE TABLE Messe_Tag (
ID integer NOT NULL AUTO_INCREMENT,
Datum date NOT NULL,
PRIMARY KEY (ID)
);
CREATE TABLE Messdiener (
ID integer NOT NULL AUTO_INCREMENT,
Name varchar(50) NOT NULL,
Letztes_dienen date DEFAULT '2017-01-01',
PRIMARY KEY (ID),
);
CREATE TABLE Messe (
ID integer NOT NULL AUTO_INCREMENT,
Datum integer NOT NULL,
PRIMARY KEY(ID),
FOREIGN KEY (Datum) REFERENCES Messe_Tag(ID)
);
CREATE TABLE Dienst_Messe (
ID integer NOT NULL AUTO_INCREMENT,
Messdiener integer,
Messe integer NOT NULL,
PRIMARY KEY (ID),
FOREIGN KEY (Messdiener) REFERENCES Messdiener(ID),
FOREIGN KEY (Messe) REFERENCES Messe(ID)
);
我想从Messe
中选择Messdiener
中的最后一个日期。 Messdiener
和Messe
与Dienst_Messe
相关,Messe
的日期与Messe_Tag
相关。当select返回空结果时,我想要使用常量日期Messdiener.Letztes_dienen
更新'2017-01-01'
。当select返回我希望用该日期更新的日期时。
表格的示例数据:
INSERT INTO Messe_Tag(ID,Datum)VALUES(1,'2017-07-11');
INSERT INTO Messe_Tag(ID,Datum)VALUES(2,'2017-05-23');
INSERT INTO Messdiener(ID,Name)VALUES(1,'Basti');
INSERT INTO Messdiener(ID,Name)VALUES(2,'Alex');
INSERT INTO Messe(ID,Datum)VALUES(1,1);
INSERT INTO Messe(ID,Datum)VALUES(2,2);
INSERT INTO Dienst_Messe(ID,Messdiener,Messe)VALUES(1,1,1);
INSERT INTO Dienst_Messe(ID,Messdiener,Messe)VALUES(1,1,2);
我使用以下更新语句尝试此操作,但不是我想要的:
UPDATE Messdiener MES
LEFT JOIN Dienst_Messe DM ON DM.Messdiener = MES.ID
LEFT JOIN Messe M ON M.ID = DM.Messe
LEFT JOIN Messe_Tag MT ON MT.ID = M.Datum
SET MES.Letztes_dienen = CASE
WHEN MT.Datum IS NOT NULL
THEN MT.Datum
ELSE '2017-01-01' END
WHERE MES.ID = ?;
使用MES.ID = 1
我想要Messdiener.Letztes_dienen
更新2017-07-11
,因为这是最后一次约会。由于MES.ID = 2
我希望使用2017-01-01
进行更新,因为Messdiener
与ID = 2
的日期不在Dienst_Messe -> Messe -> Messe_Tag
。
我的更新语句更新了列,但未使用最新日期(2017-07-11)
,而是使用最早的日期(2017-05-23)
。如果MT.Datum
为空,则该语句会成功将列Messdiener.Letztes_dienen
更新为2017-01-01
。
我认为我的更新声明中需要ORDER BY
来解决最早的日期问题,但我不知道我是如何实现这一点的。
感谢您的帮助。
答案 0 :(得分:0)
UPDATE `Messdiener` SET `letztes_dienen` = (
SELECT IFNULL(MAX(MT.Datum), '2017-01-01') FROM
`Dienst_Messe` DM
LEFT JOIN `Messe` M ON M.ID = DM.Messe
LEFT JOIN `Messe_Tag` MT ON MT.ID = M.Datum
WHERE DM.Messdiener = Messdiener.ID
)
WHERE `id` = ?;
答案 1 :(得分:0)
我尝试修改你的代码,因为最大日期可以在另外三个表中。
UPDATE Messdiener SET Letztes_dienen = (
SELECT IFNULL(
(SELECT MAX(D.Datum) FROM (
SELECT MT.Datum Datum FROM Dienst_Messe DM
LEFT JOIN Messe M ON M.ID = DM.Messe
LEFT JOIN Messe_Tag MT ON MT.ID = M.Datum
LEFT JOIN Messdiener ON DM.Messdiener = Messdiener.ID
WHERE Messdiener.ID = ?
UNION
SELECT MT.Datum Datum FROM Weihrauch_Messe WM
LEFT JOIN Messe M ON M.ID = WM.Messe
LEFT JOIN Messe_Tag MT ON MT.ID = M.Datum
LEFT JOIN Messdiener ON WM.Messdiener = Messdiener.ID
WHERE Messdiener.ID = ?
UNION
SELECT MT.Datum Datum FROM Kreuz_Messe KM
LEFT JOIN Messe M ON M.ID = KM.Messe
LEFT JOIN Messe_Tag MT ON MT.ID = M.Datum
LEFT JOIN Messdiener ON KM.Messdiener = Messdiener.ID
WHERE Messdiener.ID = ?
UNION
SELECT MT.Datum Datum FROM Assistent_Messe AM
LEFT JOIN Messe M ON M.ID = AM.Messe
LEFT JOIN Messe_Tag MT ON MT.ID = M.Datum
LEFT JOIN Messdiener ON AM.Messdiener = Messdiener.ID
WHERE Messdiener.ID = ?
) AS D)
, '2017-01-01'
)
WHERE ID = ?;
SELECT IFNULL(....) AS D), '2017-01-01');
返回正确的日期,但在更新子句中,它会触发错误:
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 '' at line 27
第27行是WHERE ID = ?;
的最后一行
为什么?你能救我吗?
我的另一个尝试是:
UPDATE Messdiener SET Letztes_dienen = (
SELECT IFNULL(MAX(MT.Datum), '2017-01-01')
FROM Messe_Tag MT
LEFT JOIN Messe M ON M.Datum = MT.ID
LEFT JOIN Dienst_Messe DM ON DM.Messe = M.ID
LEFT JOIN Weihrauch_Messe WM ON WM.Messe = M.ID
LEFT JOIN Kreuz_Messe KM ON KM.Messe = M.ID
LEFT JOIN Assistent_Messe AM ON AM.Messe = M.ID
WHERE DM.Messdiener = Messdiener.ID
AND WM.Messdiener = Messdiener.ID
AND KM.Messdiener = Messdiener.ID
AND AM.Messdiener = Messdiener.ID
)
WHERE ID = 46;
但这会将Letztes_dienen
直接设为'2017-01-01'
答案 2 :(得分:0)
我会使用view(没有重复),其中包含所有具有日期的表格。
-- I assumed that the structure of the tables is the identical.
CREATE VIEW all_data_view AS
(SELECT id, datum from Kreuz_Messe) UNION (SELECT id, datum FROM Messe);
检查结果的查询:
SELECT IFNULL(MAX(MT.Datum), '2017-01-01') FROM
`Dienst_Messe` DM
LEFT JOIN `all_data_view` AD ON AD.ID = DM.Messe
LEFT JOIN `Messe_Tag` MT ON MT.ID = AD.Datum
WHERE DM . Messdiener = 1;
因此,通过从第一个答案修改DML(用表Messe
替换表all_data_view
),您就可以实现目标。