Sql 我有一个表,需要根据字段参数进行更新或插入
我花了很多时间研究这个问题,并尝试各种解决方案,但我从来没有找到一个适合我的具体问题的解决方案。我是SQL新手,其中一些示例也令人困惑 这就是我的困境。我有一个设备表,用于跟踪数据库中特定装置的换油情况。该表如下所示:Sql 我有一个表,需要根据字段参数进行更新或插入,sql,sqlite,Sql,Sqlite,我花了很多时间研究这个问题,并尝试各种解决方案,但我从来没有找到一个适合我的具体问题的解决方案。我是SQL新手,其中一些示例也令人困惑 这就是我的困境。我有一个设备表,用于跟踪数据库中特定装置的换油情况。该表如下所示: **id UnitID Posted_On Date_Completed Note OverDueBy** 1 BT-109F 2019-02-04 2019-02-14 Hrs Overdue 23
**id UnitID Posted_On Date_Completed Note OverDueBy**
1 BT-109F 2019-02-04 2019-02-14 Hrs Overdue 23
1 BT-108G 2020-01-17 2020-01-22 Days Overdue 12
1 BT-122K 2020-01-02 2020-01-16 Days Overdue 12
1 BT-109F 2019-02-04 Days Overdue 3
MERGE INTO EQUIPMENT A
USING (SELECT * FROM EQUIPMENT B WHERE DATE_COMPLETED IS NULL) C
ON (A.UNITID=C.UNITID)
WHEN MATCHED THEN UPDATE SET A.OVERDUEBY="new value"
WHEN NOT MATCHED THEN INSERT (A.id,A.UnitID,A.Posted_On,A.Date_Completed,A.Note,A.OverDueBy)
VALUES (C.id,C.UnitID,C.Posted_On,NULL,C.Note,C.OverDueBy)
上面的示例记录需要由查询创建或更新。完成日期由技师在完成机油更换后手动输入
我希望查询做的是,检查特定单元是否有“Date_Completed”字段为空的记录,如果是,则更新“OverDueBy”字段以反映新值。如果指定单位的所有记录都填写了“Date_Completed”(完成日期)字段,则查询应创建一个新记录,该记录将包含除“Date_Completed”(完成日期)字段之外的所有字段
有人能帮我构造这样一个查询吗
谢谢
Clan首先,我会使用视图而不是表来存储任何计算数据-它减少了存储开销,并会在每次打开视图时更新计算。 如果您使用的是SQLite,您应该能够通过从其函数中减去Posted_On来返回今天的日期,例如
date('now')
或julianday('now')
——阅读并测试函数,以确保它符合您的要求。
因此,大致如下:-
create view MyView as select *, julianday('now') - julianday(Posted_On) as OverDueBy from ClansTable where Date_Completed is null;
如果要存储快照,在任何情况下都可以从视图创建表:-
create table MyStoredOverduesOn4thFeb as select * from MyView;
您可以找到已完成所有日期的单位,并创建一个新记录,如下所示:-
Create table CompletedUnits as select id, UnitID, max(posted_on) as latest_posted_on, '' as Date_Completed from ClansTable group by id, UnitID having count(*) = count(Date_Complete);
测试这个SQL,看看是否可以让它工作——注意,我已经为日期创建了一个文本字段。显然不存在这样的日期/日期时间数据类型:-
希望这有帮助
菲尔我想你需要这样的东西:
**id UnitID Posted_On Date_Completed Note OverDueBy**
1 BT-109F 2019-02-04 2019-02-14 Hrs Overdue 23
1 BT-108G 2020-01-17 2020-01-22 Days Overdue 12
1 BT-122K 2020-01-02 2020-01-16 Days Overdue 12
1 BT-109F 2019-02-04 Days Overdue 3
MERGE INTO EQUIPMENT A
USING (SELECT * FROM EQUIPMENT B WHERE DATE_COMPLETED IS NULL) C
ON (A.UNITID=C.UNITID)
WHEN MATCHED THEN UPDATE SET A.OVERDUEBY="new value"
WHEN NOT MATCHED THEN INSERT (A.id,A.UnitID,A.Posted_On,A.Date_Completed,A.Note,A.OverDueBy)
VALUES (C.id,C.UnitID,C.Posted_On,NULL,C.Note,C.OverDueBy)
不确定更新中的新值来自何处。你的问题不清楚。但是类似的方法可能会奏效。首先为列
UnitID
创建一个唯一的部分索引:
CREATE UNIQUE INDEX idx_unit ON tablename(UnitID)
WHERE Date_Completed IS NULL;
因此,对于每个UnitID
,只允许有一行Date\u Completed=null
这样的说法:
INSERT INTO tablename(id, UnitID, Posted_On, Date_Completed, Note, OverDueBy)
VALUES (?, 'BT-109F', ?, null, ?, ?)
ON CONFLICT(UnitID) WHERE Date_Completed IS NULL DO UPDATE
SET OverDueBy = ?;
仅当UnitID='BT-109F'
在Date\u Completed中没有带null的行时,才会插入新值
但是如果有这样一行,它将更新列OverDueBy
我不确定要插入什么值或更新的值是什么,因此请用适当的值替换?
。如果它确实是sqlite,我认为您不能,您需要的更像一个存储过程而不是查询,sqlite不支持存储过程。在您的位置上,我将编写3个单独的查询和一段python,根据您提到的逻辑运行它们如果您的sqlite
版本支持所谓的UPSERT,那么这就是方法。我确信UPSERT可以与我的sqlite一起工作,并且我已经尝试使用示例格式化查询,但我没有足够的经验来正确处理它。有人吗?这不是upsert的目的。这是由主键或唯一索引冲突触发的。我感谢您的帮助,这将适用于按日期过期的字段,但单位也可能因小时计读数过期。查询将由节点红色函数每天运行一次。如果PMI(换油)未完成,则查询(我希望)将更新字段中的当前工时计读数。我想我可以对Unit和IsNull(“Date_completed”)执行“select”语句过滤,如果出现错误,则插入其他更新。(只是不知道怎么做)好的,那么改用datetime()函数怎么样?我确实在node red函数中使用了datetime函数,但查询是另一个故事SQLite不支持合并。谢谢。我明天试试这个。(下午剩下的时间都得出去)。我会让你知道这是怎么回事。:)我确实创建了索引,但第二部分不起作用。我得到以下消息:ON CONFLICT子句不匹配任何主键或唯一约束。不确定下一步要尝试什么。是否复制了带有“WHERE Date_Completed is NULL”的代码?语法正确。检查这个:我做了,但我会检查链接并返回给你。我们又得出去了,所以我最早要到明天早上才能给你回电话。(医院里的家人)@forpast非常感谢你。这很有效。我很惊讶你提出了这个解决方案。我不会想到使用唯一的索引。非常聪明。:)