一个 SQL 不会写,大佬帮帮忙

94 天前
 imyasON

假如查询 SELECT COUNT(1) FROM attendance_workday WHERE date_ymd LIKE '202401%'; 大于 0 库中有值 就执行 update 语句,否则 insert 插入语句,这样写会 like 12 次 '202401%', '202402%' ... '202412%'; 一共 12 个月.

updata 和 insert 语句 每个月份的都不一样,用 sql 脚本我该怎么写,用不了代码。

一月的 插入: INSERT INTO attendance_workday (date_ymd, is_work) VALUES ('20240101', '1'), ('20240102', '1'), ('20240103', '1'), ('20240104', '1'), ('20240105', '1'), ('20240106', '0'), ('20240107', '0'), ('20240108', '1'), ('20240109', '1'), ('20240110', '1'), ('20240111', '1'), ('20240112', '1'), ('20240113', '1'), ('20240114', '0'), ('20240115', '1'), ('20240116', '1'), ('20240117', '1'), ('20240118', '1'), ('20240119', '1'), ('20240120', '0'), ('20240121', '0'), ('20240122', '1'), ('20240123', '1'), ('20240124', '1'), ('20240125', '1'), ('20240126', '1'), ('20240127', '0'), ('20240128', '0'), ('20240129', '1'), ('20240130', '1'), ('20240131', '1');

更新: UPDATE attendance_workday SET date_ymd = '20240101', is_work = '1'; UPDATE attendance_workday SET date_ymd = '20240102', is_work = '1'; UPDATE attendance_workday SET date_ymd = '20240103', is_work = '1'; UPDATE attendance_workday SET date_ymd = '20240104', is_work = '1'; UPDATE attendance_workday SET date_ymd = '20240105', is_work = '1'; UPDATE attendance_workday SET date_ymd = '20240106', is_work = '0'; UPDATE attendance_workday SET date_ymd = '20240107', is_work = '0'; UPDATE attendance_workday SET date_ymd = '20240108', is_work = '1'; UPDATE attendance_workday SET date_ymd = '20240109', is_work = '1'; UPDATE attendance_workday SET date_ymd = '20240110', is_work = '1'; UPDATE attendance_workday SET date_ymd = '20240111', is_work = '1'; UPDATE attendance_workday SET date_ymd = '20240112', is_work = '1'; UPDATE attendance_workday SET date_ymd = '20240113', is_work = '1'; UPDATE attendance_workday SET date_ymd = '20240114', is_work = '0'; UPDATE attendance_workday SET date_ymd = '20240115', is_work = '1'; UPDATE attendance_workday SET date_ymd = '20240116', is_work = '1'; UPDATE attendance_workday SET date_ymd = '20240117', is_work = '1'; UPDATE attendance_workday SET date_ymd = '20240118', is_work = '1'; UPDATE attendance_workday SET date_ymd = '20240119', is_work = '1'; UPDATE attendance_workday SET date_ymd = '20240120', is_work = '0'; UPDATE attendance_workday SET date_ymd = '20240121', is_work = '0'; UPDATE attendance_workday SET date_ymd = '20240122', is_work = '1'; UPDATE attendance_workday SET date_ymd = '20240123', is_work = '1'; UPDATE attendance_workday SET date_ymd = '20240124', is_work = '1'; UPDATE attendance_workday SET date_ymd = '20240125', is_work = '1'; UPDATE attendance_workday SET date_ymd = '20240126', is_work = '1'; UPDATE attendance_workday SET date_ymd = '20240127', is_work = '0'; UPDATE attendance_workday SET date_ymd = '20240128', is_work = '0'; UPDATE attendance_workday SET date_ymd = '20240129', is_work = '1'; UPDATE attendance_workday SET date_ymd = '20240130', is_work = '1'; UPDATE attendance_workday SET date_ymd = '20240131', is_work = '1';

3084 次点击
所在节点    程序员
19 条回复
hay313955795
94 天前
这要写存储过程呗。
为什么不用业务代码实现
aahao
94 天前
iyiluo
94 天前
gpt 啊,这种活干嘛不问 gpt
lsk569937453
94 天前
直接写代码实现。用 sql 实现的话后期维护够你喝一壶的
vhjxbc
94 天前
好的,我理解你的需求了。你想检查 attendance_workday 表中是否有某个特定月份(比如,2024 年 1 月)的记录。如果有记录,你想执行一个 UPDATE 语句;否则,你想执行一个 INSERT 语句。

下面是一个可以满足你需求的脚本:

sql
Copy code
DECLARE @MonthToCheck VARCHAR(6) = '202401'; -- 将此值更改为所需的月份

IF EXISTS (SELECT 1 FROM attendance_workday WHERE date_ymd LIKE @MonthToCheck + '%')
BEGIN
-- 更新语句
UPDATE attendance_workday
SET is_work = CASE
WHEN date_ymd = @MonthToCheck + '01' THEN '1'
WHEN date_ymd = @MonthToCheck + '02' THEN '1'
-- 依此类推,覆盖月份中的所有天
WHEN date_ymd = @MonthToCheck + '31' THEN '1'
END
WHERE date_ymd LIKE @MonthToCheck + '%';
END
ELSE
BEGIN
-- 插入语句
INSERT INTO attendance_workday (date_ymd, is_work)
VALUES
(@MonthToCheck + '01', '1'),
(@MonthToCheck + '02', '1'),
-- 依此类推,覆盖月份中的所有天
(@MonthToCheck + '31', '1');
END
在运行脚本之前,用实际的月份替换 @MonthToCheck 。这个脚本使用了条件性的 EXISTS 检查来判断表中是否存在指定月份的记录。如果存在记录,就执行 UPDATE 语句;否则,执行 INSERT 语句。脚本中包含了月份中每一天的占位符,你需要根据实际情况调整。
dog82
94 天前
不是有 ON DUPLICATE KEY 和 merge 语法么,看能不能用上
rxmt
94 天前
GPT 侠帮你问了。。

要在 SQL 脚本中实现您描述的功能,可以使用一个控制流程结构来先检查每个月份是否存在数据,然后根据检查结果执行相应的 INSERT 或 UPDATE 操作。但请注意,SQL 本身并不直接支持循环或条件分支,这通常是通过存储过程或脚本语言来实现的。下面是一个简化的示例,说明如何为一个月份实现这个过程。

sql
Copy code
-- 检查 2024 年 1 月的数据是否存在
DECLARE @count INT;
SELECT @count = COUNT(1) FROM attendance_workday WHERE date_ymd LIKE '202401%';

-- 根据结果执行相应操作
IF @count > 0
BEGIN
-- 数据存在时,执行更新操作
UPDATE attendance_workday SET is_work = '1' WHERE date_ymd = '20240101';
-- ... 后续更新操作
END
ELSE
BEGIN
-- 数据不存在时,执行插入操作
INSERT INTO attendance_workday (date_ymd, is_work)
VALUES
('20240101', '1'),
-- ... 后续插入操作
('20240131', '1');
END
这个示例是在假设您使用的是支持 T-SQL (例如 SQL Server )的数据库系统。如果您使用的是其他类型的数据库系统(如 MySQL 、PostgreSQL 等),可能需要使用不同的语法。

此外,对于您描述的 12 个月份,您需要为每个月份重复这个过程。这可能导致代码量较大。为了简化这一过程,您可能需要考虑使用数据库的编程功能(如存储过程)或者将逻辑移动到应用程序代码中,这样可以更容易地实现循环和条件逻辑。

在实现此类操作时,请确保考虑事务的使用,以保持数据的一致性和完整性。如果您不熟悉高级 SQL 技巧或存储过程的编写,建议咨询熟悉数据库编程的专业人士。
corcre
94 天前
这不工作日历吗...
你有数据的话全都查到临时表里面开个游标然后在实体表里面 if exists update ..... else insert....不就好了, 一年的数据量才 365 天吧
lll5758
94 天前
啊?那还要后端干什么呢,直接连接数据库得了
yjxjn
94 天前
如果你想在数据库中进行检查,然后根据条件执行不同的 SQL 语句,可以使用存储过程( Stored Procedure )或者函数。下面是一个简单的例子,假设你使用的是 MySQL 数据库:

-- 创建存储过程
DELIMITER //

CREATE PROCEDURE UpdateOrInsertForMonth(IN target_month VARCHAR(6))
BEGIN
DECLARE record_count INT;

-- 检查记录数量
SELECT COUNT(1) INTO record_count FROM attendance_workday WHERE date_ymd LIKE CONCAT(target_month, '%');

-- 根据记录数量执行不同的 SQL 语句
IF record_count > 0 THEN
-- 如果有记录,则执行 UPDATE 语句
UPDATE your_table SET your_column = 'new_value' WHERE date_ymd LIKE CONCAT(target_month, '%');
ELSE
-- 如果没有记录,则执行 INSERT 语句
INSERT INTO your_table (date_ymd, your_column) VALUES ('20240101', 'new_value');
-- 这里请根据实际表结构和字段进行修改
END IF;
END //

DELIMITER ;

上述例子中,your_table 和 your_column 需要替换为你实际的表名和列名。存储过程中的逻辑可以根据你的需求进行修改。

然后,你可以调用这个存储过程,传入不同的月份作为参数,例如:

-- 调用存储过程,传入月份 '202401'
CALL UpdateOrInsertForMonth('202401');
liprais
94 天前
楼上这些深刻揭示了如果你不会写 code,那大模型生成的 code 对你也没什么用
RockShake
94 天前
你应该有数据库的读写权限,怎么会用不了代码呢,VBA 也是代码,这个逻辑放到代码层面实现会简单很多
xuanbg
94 天前
代码写个循环,给 sql 传参数“'2024xx”就行
imyasON
94 天前
谢谢各位,不写代码是因为我没有数据库连接权限,只能把脚本写好交给别人执行,按照上面的写了一个存储过程,我本地测下
shen13176101
94 天前
路看窄了,不应该把这个看作是 sql ,应该看作是需求。以需求的角度来写 sql ,
ZField
94 天前
= = 如果数据量较少并且单次使用,不如直接大量的单条语句,既简单又可以控制风险
gkinxin
94 天前
@Livid #5 vhjxbc #7 rxmt #10 yjxjn GPT 回答
isnullstring
94 天前
限制一定要 SQL 的话,两种方式
1 、存储过程,游标循环传日期进去处理,调用是一个存储过程,处理是一个存储过程
2 、动态 SQL ,也是游标循环传日期,一个存储过程
3 、按 date_ymd 的前 6 位汇总,创建临时表记录对应日期库存是否大于 0 ,然后分别写 Insert 和 update ,条件就是临时表了
我会选第三种,不需要用游标,不需要分存储过程,不需要动态 SQL ,不需要 Ctrl+CV ,不需要管日期,即使你的 attendance_workday 用了 100 年 ,表中数据才 100*365=36500 ,当然我相信里面还有其他细节没考虑,自行完善
hackerfans
94 天前
BEGIN
DECLARE month_num INT;

SET month_num = 1; -- Start with January

WHILE month_num <= 12 DO
DECLARE month_str CHAR(2);
SET month_str = LPAD(month_num, 2, '0'); -- Format month as 01, 02, ...

DECLARE count_rows INT;
SET count_rows = (SELECT COUNT(1) FROM attendance_workday WHERE date_ymd LIKE CONCAT('2024', month_str, '%'));

IF count_rows > 0 THEN
-- Perform UPDATE statements for the current month
-- Replace placeholders with actual UPDATE statements for each month
EXECUTE IMMEDIATE CONCAT('UPDATE attendance_workday SET date_ymd = '2024', month_str, '01', ', is_work = '1' WHERE date_ymd LIKE '2024', month_str, '%'');
-- Add similar UPDATE statements for other dates in the month
ELSE
-- Perform INSERT statements for the current month
-- Replace placeholders with actual INSERT statements for each month
EXECUTE IMMEDIATE CONCAT('INSERT INTO attendance_workday (date_ymd, is_work) VALUES (''2024', month_str, '01'', ''1''), (''2024', month_str, '02'', ''1''), ...');
-- Add remaining date-is_work pairs for the month
END IF;

SET month_num = month_num + 1; -- Move to the next month
END WHILE;
END

这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。

https://www.v2ex.com/t/1013983

V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。

V2EX is a community of developers, designers and creative people.

© 2021 V2EX