我有3张桌子。
培训表:
CREATE TABLE `training_session` (
`_id` INTEGER PRIMARY KEY AUTOINCREMENT,
`date_time` TEXT NOT NULL UNIQUE,
`training_day_id` INTEGER,
`duration` INTEGER,
FOREIGN KEY(`training_day_id`) REFERENCES `training_program_day`(`_id`) ON DELETE SET NULL
);
培训计划的天数表:
CREATE TABLE `training_program_day` (
`_id` INTEGER PRIMARY KEY AUTOINCREMENT,
`name` TEXT NOT NULL,
`program_id` INTEGER,
`number` INTEGER NOT NULL,
FOREIGN KEY(`program_id`) REFERENCES `training_program`(`_id`) ON DELETE CASCADE
);
培训计划表:
CREATE TABLE `training_program` (
`_id` INTEGER PRIMARY KEY AUTOINCREMENT,
`name` INTEGER NOT NULL UNIQUE
);
在培训日表中,有一列number
确定了培训日在计划中的执行顺序。我从number
表中获得了上一个培训日的training_session
:
SELECT tpd.number
FROM training_session AS ts
LEFT JOIN training_program_day AS tpd ON ts.training_day_id = tpd._id
WHERE ts.training_day_id IS NOT NULL
ORDER BY ts.date_time
DESC LIMIT 1
我想在下一个训练日获取数据,因此我将上面的代码用作子查询,并找到一个训练日,其编号为1。
SELECT
tp.name AS program,
tpd.name AS training_day
FROM training_program_day AS tpd
LEFT JOIN training_program AS tp ON tpd.program_id = tp._id
WHERE tpd.number = 1 + (
SELECT tpd.number
FROM training_session AS ts
LEFT JOIN training_program_day AS tpd ON ts.training_day_id = tpd._id
WHERE ts.training_day_id IS NOT NULL
ORDER BY ts.date_time
DESC LIMIT 1)
如果在子查询中找到的当天的number
不是training_prorgam_day
表中最大的日期,则此查询正确运行。当然,否则什么也不会回来。但是训练程序中的日期必须循环,因此,如果子查询中找到的number
是最大的一天,那么我想获取程序中第一天的数据。但是我不知道该怎么做。我最近开始学习SQLite,因此不了解其所有功能。如果您说我的要求无效,我不会感到惊讶。我将非常感谢您的优化。
例如,我在表中有这样的数据:
答案 0 :(得分:0)
该查询似乎正在运行,但是我认为它可以更轻松,更高效地编写。等待您的优化。
-- 4) Find the data for the day you want
SELECT tp.name AS prog_name, tpd4.name AS day_name, tpd4._id AS day_id
FROM (
-- 3) If there is no such day, take the first day from this program
SELECT
last_prog_id,
ifnull(last_number_plus_1, 1) AS desired_number
FROM (
-- 2) Looking for a training day from the same program, whose number is 1 more.
SELECT
last_prog_id,
tpd2.number AS last_number_plus_1
FROM (
-- 1) Find the training day we trained for the last time
SELECT
tpd1.program_id AS last_prog_id,
tpd1.number AS last_number
FROM training_session AS ts
LEFT JOIN training_program_day AS tpd1 ON ts.training_day_id = tpd1._id
WHERE ts.training_day_id IS NOT NULL
ORDER BY ts.date_time DESC
LIMIT 1
)
LEFT JOIN training_program_day AS tpd2
ON last_prog_id = tpd2.program_id AND last_number + 1 = tpd2.number
)
LEFT JOIN training_program_day AS tpd3
ON last_prog_id = tpd3.program_id AND last_number_plus_1 = tpd3.number
)
INNER JOIN training_program_day AS tpd4
ON last_prog_id = tpd4.program_id AND desired_number = tpd4.number
INNER JOIN training_program AS tp
ON last_prog_id = tp._id
答案 1 :(得分:0)
子查询last
如上所述。
然后,外部查询中的第一个联接将搜索两行,其中第一行具有较大的数字,第二行具有数字1
。
然后ORDER BY
/ LIMIT
仅返回编号最大的行,即存在的下一个,否则返回第一个。
SELECT next._id, next.name, p.name
FROM (SELECT d.program_id, d.number
FROM training_program_day AS d
JOIN training_session AS s ON d._id = s.training_day_id
ORDER BY s.date_time DESC
LIMIT 1) AS last
JOIN training_program_day AS next ON next.program_id = last.program_id
AND next.number IN (last.number + 1, 1)
JOIN training_program AS p ON next.program_id = p._id
ORDER BY next.number DESC
LIMIT 1;