请耐心等待我,我不擅长SQL:
我有三张桌子
1)通知 - 存储我的所有数据
2)GroupTable - 具有组名和相关ID
3)GroupUser - 此表将Uname和Udob映射到GroupTable中的一个组。
现在,在我从Notifications中获取记录之前,我想检查GroupTable for GroupID取这个GroupID并在GroupUser中查找此GroupID中的所有记录(Names,DOB,因为它们是唯一的)一旦我得到这些数据,我想要获取名称和DOB的通知表中的记录按日期的升序排列:
到目前为止,我有以下查询,它只是我感到不满意,我认为这可以改进:
SELECT
*
FROM
(SELECT
*
FROM Notifications
WHERE
DateToNotify < '2016-03-24' AND
NotificationDateFor IN
(SELECT gu.Name
FROM GroupUser AS gu
INNER JOIN GroupTable AS gt ON
gu.GroupID = gt._id AND
gt.GroupName = "Groupn"
) AND
DOB IN
(SELECT gu.DOB
FROM GroupUser AS gu
INNER JOIN GroupTable AS gt ON
gu.GroupID = gt._id AND
gt.GroupName = "Groupn"
)
) as T
ORDER BY
SUBSTR(DATE('NOW'), 0) > SUBSTR(DateToNotify, 0)
, SUBSTR(DateToNotify, 0)
答案 0 :(得分:1)
我认为你不会用连接而不是IN子句来加快速度。重写可能甚至不会改变执行计划,因为dbms无论如何都试图以最佳方式访问数据。
有些奇怪的是,您不会查找与name和dob匹配的组用户,但只能确保有与该名称匹配的组用户以及 - 可能是其他 - 与dob匹配的组用户。但正如你所说的那样,查询工作正常,好的。
编辑:好的,根据您的评论,您实际上希望在 名称和dob上进行groupuser匹配。所以你要找的是
AND (NotificationDateFor, DOB) IN (SELECT gu.Name, gu.DOB FROM ...)
但SQLite不支持这种漂亮的语法(Oracle是我所知道的唯一的dbms)。
所以你加入或使用EXISTS。
加入:
select distinct n.*
from notifications n
join
(
select name, dob
from groupuser
where groupid = (select _id from grouptable where groupname = 'groupn')
) as gu on n.notificationdatefor = gu.name and n.dob = gu.dob
where n.datetonotify < '2016-03-24'
order by date('now') > n.datetonotify, n.datetonotify;
使用EXISTS:
select *
from notifications n
where datetonotify < '2016-03-24'
and exists
(
select *
from groupuser gu
where gu.groupid = (select _id from grouptable where groupname = 'groupn')
and gu.name = n.notificationdatefor
and gu.dob = n.dob
)
order by date('now') > n.datetonotify, n.datetonotify;