我正在尝试构建一个支持系统,我现在面临一个复杂的查询。我的SQLite表中有几张表看起来像这样(略微简化):
CREATE TABLE "assign" (
"id" INTEGER NOT NULL PRIMARY KEY,
"created" DATETIME NOT NULL,
"is_assigned" SMALLINT NOT NULL,
"user_id" INTEGER NOT NULL REFERENCES "user" ("id")
);
CREATE TABLE "message" (
"id" INTEGER NOT NULL PRIMARY KEY,
"created" DATETIME NOT NULL,
"user_id" INTEGER REFERENCES "user" ("id") ,
"text" TEXT NOT NULL
);
CREATE TABLE "user" (
"id" INTEGER NOT NULL PRIMARY KEY,
"name" VARCHAR(255) NOT NULL
);
我现在想做一个查询,它给我*一个用户列表,最后创建的Assign.is_assigned == False,最后创建的Message晚于最后创建的Assign *。所以我现在有以下(伪)查询:
SELECT *
FROM user
WHERE ((IF (
SELECT is_assigned
FROM assign
WHERE assign.user_id = user.id
ORDER BY created DESC LIMIT 1
) = False)
AND ((
SELECT created
FROM message
WHERE message.user_id = user.id
ORDER BY created DESC
LIMIT 1
) > (
SELECT created
FROM assign
WHERE assign.user_id = user.id
ORDER BY created DESC
LIMIT 1))
);
这对我来说很有意义,但遗憾的是没有给电脑。我想我需要使用case语句甚至连接或者什么,但我不知道如何。有没有人知道如何做到这一点?
答案 0 :(得分:1)
尝试以下我在mysql中创建的查询
SELECT u.id AS 'user',u.name AS 'User_Name', ass.created AS 'assign_created',ass.is_assigned AS 'is_assigned',
msg.created AS 'message_created'
FROM `user` AS u
LEFT JOIN `assign` AS ass ON ass.`user_id` = u.`id`
LEFT JOIN `message` AS msg ON msg.`user_id` = u.id
LEFT JOIN (SELECT u.id AS 'user_id',u.name AS 'username',ass.created AS 'max_ass_created',ass.is_assigned AS 'assigned'
FROM `user` AS u
LEFT JOIN `assign` AS ass ON ass.`user_id` = u.`id`
LEFT JOIN `message` AS msg ON msg.`user_id` = u.`id`
GROUP BY u.id ORDER BY ass.created DESC) AS sub ON sub.user_id = u.id
WHERE (sub.assigned IS FALSE AND msg.created < sub.max_ass_created)
检查您的方案的 SQL Fiddle
希望这能解决您的问题!
答案 1 :(得分:1)
你不需要那里的IF,而且SQLite没有False
,但是,你的查询是非常正确的:
SELECT *
FROM "user"
WHERE NOT (SELECT is_assigned
FROM assign
WHERE user_id = "user".id
ORDER BY created DESC
LIMIT 1)
AND (SELECT created
FROM message
WHERE user_id = "user".id
ORDER BY created DESC
LIMIT 1
) > (
SELECT created
FROM assign
WHERE user_id = "user".id
ORDER BY created DESC
LIMIT 1)