【问题标题】:SQL Update If exist, Insert if not by checking multiple columns [duplicate]SQL更新如果存在,如果不通过检查多列插入[重复]
【发布时间】:2022-10-13 20:40:53
【问题描述】:

我有两个这样的表:

  1. files
    id customer bucket path size createdAt
    4043973 40 foo account-40/upload/26f36a10-4aeb-11ed-8a5a-49f4b61eae34_result.png 2238 2022-10-13 11:35:35
    4043972 40 foo account-40/upload/26e6bfe0-4aeb-11ed-8e31-571f8b74e4db_result.png 1985 2022-10-13 11:35:35
    4043971 40 foo account-40/upload/26dfe210-4aeb-11ed-8e31-571f8b74e4db_result.png 1985 2022-10-13 11:35:35
    1. summary
    id fileId month year downloads
    1 585086 9 2022 1
    2 584821 9 2022 1
    3 584872 9 2022 1

    系统中处理的文件有动作日志。这些日志仍未分类。每个上传的文件都会添加到files 表中。

    每天对文件进行的下载应保存到汇总表中。如果该文件在该月第一次处理,则应添加一个新行。第一个之后的操作应将downloads 列增加+1。

    我可以用 3 个查询来做到这一点。像这样:

    检查文件是否存在:

    SELECT 
        id 
    FROM 
        summary
    WHERE
        fileId=(SELECT id FROM cloud_storage_files WHERE path=':filePath') AND
        month=:month AND
        year=:year
    

    如果存在则插入:

    INSERT INTO 
        summary (fileId, month, year, downloads)
    SELECT id, :month, :year, 1 FROM files WHERE path=':filePath'
    

    如果没有更新:

    UPDATE
        summary,
        files
    SET
        summary.downloads = summary.downloads + 1
    WHERE
        files.path=':filePath' AND files.id=summary.fileId
    

    但是由于每天要处理很多文件,所以有很多数据,我想在一个 sql 查询中完成所有操作。

    到目前为止,我试图这样做:

    IF(SELECT fileId FROM summary 
        WHERE fileId = :fileId
        AND `month` = :month
        AND `year` = :year) 
    
    THEN    
        INSERT INTO 
        summary (fileId, month, year, downloads) VALUES (:fileId, :month, :year, 1)
    ELSE
        UPDATE
            summary,
            files
        SET
            summary.downloads = summary.downloads + 1
        WHERE
            files.path='foo-bar-bar' AND files.id=summary.fileId
    

    但还没有骰子。我很想听听任何对此问题有解决方案或建议的人。

    谢谢!

【问题讨论】:

  • SQL Server <> MySQL;你是做什么的真的使用?
  • @Larnu 这是 MySQL 错误的标签。已更正
  • (fileId, month, year) + INSERT .. ODKU 的唯一索引。

标签: mysql sql


【解决方案1】:

按文件 ID 和年月创建唯一索引:

CREATE INDEX idx_uni_fileId_month_year
ON summary (fileId, month, year);

然后插入重复自动检查:

INSERT INTO summary (fileId, month, year, downloads)
SELECT id, :month, :year, 1 
FROM files 
WHERE path = ':filePath' 
-- or WHERE path IN ( {filepaths list} )
ON DUPLICATE KEY 
UPDATE downloads = downloads + 1;

如果已经存在具有相同(fileId, month, year) 的行,那么它将被更新并增加下载量,否则将插入新行。

当然,SELECT 可能返回不止一行,每一行都会被独立处理。

【讨论】:

    猜你喜欢
    • 2019-10-17
    • 2012-12-13
    • 1970-01-01
    • 2019-01-16
    • 2018-06-10
    • 1970-01-01
    • 2011-04-30
    • 1970-01-01
    • 2011-07-14
    相关资源
    最近更新 更多