Mysql h
(我还添加了一个ORDER BY子句,只是为了使结果更具确定性。)一些示例数据和期望的结果将有助于澄清关系扫描从派生事件派生的事件?关于您的示例:您正在搜索日历a和B,并且正在筛选出第100行,因为第101行已经存在?如果你只想搜索一个?你想返回100和150?你尝试过你的方法吗?我认为您的查询中的口头描述和实现的逻辑之间存在差异,因为您的查询实际上会过滤掉派生词并保留它们的原始值。它可能会保留不符合其他标准(例如,不符合日期范围)的事件的衍生产品。也许你真的想要Mysql h,mysql,sql,performance,Mysql,Sql,Performance,(我还添加了一个ORDER BY子句,只是为了使结果更具确定性。)一些示例数据和期望的结果将有助于澄清关系扫描从派生事件派生的事件?关于您的示例:您正在搜索日历a和B,并且正在筛选出第100行,因为第101行已经存在?如果你只想搜索一个?你想返回100和150?你尝试过你的方法吗?我认为您的查询中的口头描述和实现的逻辑之间存在差异,因为您的查询实际上会过滤掉派生词并保留它们的原始值。它可能会保留不符合其他标准(例如,不符合日期范围)的事件的衍生产品。也许你真的想要id not in(SELECT
id not in(SELECT derivedfrom\u id…
而不是derivedfrom\u id not in(SELECT id…
),尽管你需要在子查询中过滤掉空值。也许我不理解你的问题,但你接受的答案对我来说似乎很复杂。如果有另一个事件添加到上面的列表中,id=102,derivedfrom_id=100,那么查询的输出应该是什么?(101150)或(101102150)?或者(102150)?谢谢。这是可行的,但除了将子选择重构到主查询中之外,这与我当前的工作查询相同,包括约束的重复,即,parent\u id in…
和start>=…
。此解决方案取决于derivedfrom\u id大于id。假设它们是Varchar(32)我不一定认为是这样。是的,你是对的。我的假设基于示例数据。如果这个假设不成立,我建议的解决方案将不得不依赖于一些创建的时间戳。我会相应地更新我的答案。我以前没有考虑过这个高雅的解决方案。我刚刚开始另一个悬赏,并将分配给这个答案。非常感谢。这与赏金或分数无关。如果这对你有帮助,欢迎你!当然不是分数,但最好的答案应该是悬赏。
TABLE event (
`id` varchar(32) NOT NULL,
`start` datetime,
`end` datetime,
`derivedfrom_id` varchar(32),
`parent_id` varchar(32) NOT NULL
)
SELECT id, start, parent_id
FROM event
WHERE parent_id in (<list of calendars>)
AND start >= 'some date'
LIMIT x
SELECT id, start, parent_id
FROM event
WHERE parent_id in (<list_of_calendars>)
AND start >= 'some date'
AND (/* the part below duplicates the previous conditions */
derivedfrom_id is not null
or id not in (
SELECT derivedfrom_id
FROM event
WHERE parent_id in (<list_of_calendars>)
AND start >= 'some date'
AND derivedfrom_id is not null
)
)
LIMIT x
│ *ID* │ *DERIVEDFROM_ID* │ *PARENT_ID* │ *START*
├──────┼──────────────────┼─────────────┼─────────────────
│ 100 │ - │ A │ 2014-11-18 15:00
│ 101 │ 100 │ B │ 2014-11-18 15:00
│ 150 │ - │ A │ 2014-11-20 08:00
Select a.id, a.start, a.parent_id from
event a , event b
Where a.parent_id in (<list_of_calendars>)
And a.start >= 'some date'
And b.parent_id = a.parent_id
And b.start = a.start
And a.id != b.derivedfrom_id
Limit x
SELECT id, start, parent_id, text, IFNULL(derivedfrom_id, id) as grouper
FROM event
WHERE parent_id in (<list_of_calendars>)
AND start >= '<some date>'
GROUP BY grouper
LIMIT <x>
SELECT e1.* FROM event e1
INNER JOIN
(
SELECT max(id) maxId, IFNULL(derivedfrom_id, id) as grouper
FROM event
WHERE parent_id in (<list_of_calendars>)
AND start >= '<some date>'
GROUP BY grouper
) e2
on e1.id = e2.maxId
LIMIT <x>
SELECT e1.* FROM event e1
INNER JOIN
(
SELECT max(created) c, IFNULL(derivedfrom_id, id) grouper
FROM event
WHERE parent_id IN (<list_of_calendars>)
AND start >= '<some date>'
GROUP BY grouper
) e2
ON (e1.id = e2.grouper AND e1.created = c) OR (e1.derivedfrom_id = e2.grouper AND e1.created = c)
LIMIT <x>
SELECT id, start, parent_id
FROM event
LEFT JOIN (
SELECT DISTINCT derived_id AS id FROM event
WHERE start >= 'some date' AND parent_id IN (<calendars>)
) omit
ON omit.id = event.id
WHERE parent_id IN (<calendars>)
AND start >= 'some date'
AND omit.id IS NULL
LIMIT x
SELECT e.id, e.start, e.parent_id
FROM event e
WHERE parent_id IN (<calendars>)
AND start >= 'some date'
AND (SELECT e2.id FROM event e2 /* and does not have derived events */
WHERE e2.derived_id = e.id
AND e2.start >= 'some date'
LIMIT 1) IS NULL
LIMIT x
SELECT e.*
FROM `event` e # 'e' from 'event'
LEFT JOIN `event` d # 'd' from 'derived'; `LEFT JOIN` gets ALL entries from `e`
ON e.id = d.derivedfrom_id # match an event `e` with all those `d` derived from it
WHERE d.id IS NULL # keep only events `e` without derived events `d`
;
AND NOT EXISTS (SELECT 1 FROM event d WHERE d.derivedfrom_id = e.id)
AND NOT EXISTS ( SELECT 1
FROM event d
WHERE d.derivedfrom_id = e.id
AND d.parent_id IN parent_id IN (<list of calendars>)
AND d.start > 'some date'
)
SELECT e.id
, e.start
, e.parent_id
FROM event e
LEFT
JOIN event d
ON d.derivedfrom_id = e.id
AND d.parent_id IN (<list of calendars>)
AND d.start >= 'some date'
WHERE d.derivedfrom_id IS NULL
AND e.parent_id IN (<list of calendars>)
AND e.start >= 'some date'
ORDER BY e.id
LIMIT x