1

说,我这里有一张桌子。该表具有以下结构(考试日期、学生姓名和获得的分数)

D       NAME    MARKS
2001-01-01  a   1
2001-01-04  a   4
2001-01-06  a   3
2001-01-08  a   3
2001-01-01  b   1
2001-01-10  b   15
2001-01-01  c   1
2001-01-06  c   2
2001-01-08  c   5
2001-01-10  c   7

我想更新表格,给那些没有每个测试条目的学生打 0 分。更新表应如下所示

D   NAME    MARKS
2001-01-01  a   1
2001-01-02  a   0
2001-01-04  a   4
2001-01-06  a   3
2001-01-08  a   3
2001-01-02  a   0
2001-01-01  b   1
2001-01-02  b   0
2001-01-04  b   0
2001-01-06  b   0
2001-01-08  b   0
2001-01-10  b   15
2001-01-01  c   1
2001-01-02  c   2
2001-01-04  c   0
2001-01-06  c   0
2001-01-08  c   5
2001-01-10  c   7

到目前为止,我能弄清楚的唯一解决方案(非常非常慢的查询)是:

SELECT DISTINCT(D) FROM tableA;
SELECT DISTINCT(NAME) FROM tableA;

使用 PHP,在嵌套循环中进行 sql 查询

INSERT IGNORE (D,NAME,MARKS)($D,$NAME,0);

但是,整个代码需要太多时间(以分钟计),因为有超过 50k 行。

有更好的建议吗?

4

1 回答 1

4

可能对可能的日期和可能的名称进行交叉连接,然后根据当前结果左连接:-

INSERT INTO A (D, name, marks)
SELECT Dates.D, Names.name, 0
FROM (SELECT DISTINCT D FROM A) Dates
CROSS JOIN  (SELECT DISTINCT name FROM A) Names
LEFT OUTER JOIN A
ON Dates.D = A.D AND Names.name = A.name
WHERE A.name IS NULL

请注意,这确实假设每天至少有一个人有一个标记。

如果您有一个名称表和一个日期表,并且只使用表 A 中这些行的 ID,那就更好了

如果您想在某个日期范围内执行此操作,即使那天没有人得到标记:-

INSERT INTO A (D, name, marks)
SELECT Dates.aDate, Names.name, 0
FROM 
(
    SELECT DATE_ADD('2001-01-01', INTERVAL units.i + tens.i * 10 + hundreds.i * 100 DAY) AS aDate
    FROM (SELECT 0 AS i UNION SELECT 1 UNION SELECT 2 UNION SELECT 3 UNION SELECT 4 UNION SELECT 5 UNION SELECT 6 UNION SELECT 7 UNION SELECT 8 UNION SELECT 9) units
    CROSS JOIN (SELECT 0 AS i UNION SELECT 1 UNION SELECT 2 UNION SELECT 3 UNION SELECT 4 UNION SELECT 5 UNION SELECT 6 UNION SELECT 7 UNION SELECT 8 UNION SELECT 9) tens
    CROSS JOIN (SELECT 0 AS i UNION SELECT 1 UNION SELECT 2 UNION SELECT 3 UNION SELECT 4 UNION SELECT 5 UNION SELECT 6 UNION SELECT 7 UNION SELECT 8 UNION SELECT 9) hundreds
    HAVING aDate BETWEEN '2001-01-01' AND '2001-12-30'
) Dates
CROSS JOIN  
(
    SELECT DISTINCT name 
    FROM A
) Names
LEFT OUTER JOIN A
ON Dates.aDate = A.D AND Names.name = A.name
WHERE A.name IS NULL
于 2013-07-12T20:17:26.893 回答