复杂的 CoreData 查询(还需要 SQL 语法)?

发布于 2024-12-03 21:09:20 字数 950 浏览 2 评论 0原文

我有 2 个实体:

Performance.start (NSDate)    Location.coordinates
Performance.end   (NSDate)    Location.name_extern
Performance.location   <<-->  Location.performances

我有一个用于 UITableViewNSFetchedResultsController,使用以下代码设置:

[[NSFetchedResultsController alloc] initWithFetchRequest:fetchRequest 
                                    managedObjectContext:self.managedObjectContext 
                                      sectionNameKeyPath:@"location.name_extern" 
                                               cacheName:nil];

因此数据按位置(它们的名称)分为多个部分。

现在我有一个 NSDate 类型的变量 selectedTime,并且想要获取(如果可能的话,使用一次获取)以下内容:

  1. 每个位置只有 2 个表演:
    • 正在运行的性能(selectedTime BETWEEN {start, end})
    • 将在选定时间运行的演出之后开始的演出

我真的在这里迷失了:-/ Even如果你能给我这样一个获取/查询的 SQL 语句,我至少会知道该往哪个方向走。

I have 2 entities:

Performance.start (NSDate)    Location.coordinates
Performance.end   (NSDate)    Location.name_extern
Performance.location   <<-->  Location.performances

I have a NSFetchedResultsController for my UITableView set up with the following code:

[[NSFetchedResultsController alloc] initWithFetchRequest:fetchRequest 
                                    managedObjectContext:self.managedObjectContext 
                                      sectionNameKeyPath:@"location.name_extern" 
                                               cacheName:nil];

So the data is divided into sections by locations (their names).

Now I have a variable selectedTime of type NSDate and want to fetch (with a single fetch if possible) the following:

  1. Only 2 Performances per Location:
    • The Performance that is running (selectedTime BETWEEN {start, end})
    • The Performance that will start after the one that is running at the selected time

I'm really lost here :-/ Even if you could just give me the SQL statement for such a fetch/query I would at least know which direction to head..

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

薄荷→糖丶微凉 2024-12-10 21:09:20

使用 SQL,您可以尝试这样的事情:

SELECT *
FROM Performance p, (
    SELECT *
    FROM Performance
    WHERE start <= selectedTime AND end >= selectedTime
    ORDER BY start ASC
    LIMIT 1
) AS p1
WHERE p.start >= p1.start
ORDER BY p.start ASC
LIMIT 2

尽管您必须决定如何处理当时没有性能运行的情况。

使用 Core Data,您可以简单地按开始日期 (ASC) 对它们进行排序,开始 <= selectedTime,返回 2 个结果,并(在代码中?)检查第一个结果的结束日期是否 >= selectedTime。

Using SQL, you could try something like this:

SELECT *
FROM Performance p, (
    SELECT *
    FROM Performance
    WHERE start <= selectedTime AND end >= selectedTime
    ORDER BY start ASC
    LIMIT 1
) AS p1
WHERE p.start >= p1.start
ORDER BY p.start ASC
LIMIT 2

Although you do have to decide how to handle the case where there is no performance running at that moment.

With Core Data, you could simply order them by start date (ASC), with start <= selectedTime, return 2 results, and (in code?) check whether or not the first result's end date is >= selectedTime.

我的鱼塘能养鲲 2024-12-10 21:09:20

呃..我想我找到了最终的解决方案..

获取非常简单:

NSEntityDescription *entity = [NSEntityDescription 
                               entityForName:@"Performance" inManagedObjectContext:self.managedObjectContext];
[fetchRequest setEntity:entity];

NSSortDescriptor *sort1 = [[NSSortDescriptor alloc] 
                          initWithKey:@"location.name_extern" ascending:YES];
NSSortDescriptor *sort2 = [[NSSortDescriptor alloc] 
                           initWithKey:@"start" ascending:YES];
[fetchRequest setSortDescriptors:[NSArray arrayWithObjects:sort1,sort2,nil]];

[fetchRequest setFetchBatchSize:20];

NSFetchedResultsController *theFetchedResultsController = 
[[NSFetchedResultsController alloc] initWithFetchRequest:fetchRequest 
                                    managedObjectContext:self.managedObjectContext 
                                      sectionNameKeyPath:@"location.name_extern" 
                                               cacheName:nil];

使用以下谓词:

NSPredicate *predicate = [NSPredicate predicateWithFormat:@"end > %@",selectedTime];

[fetchRequest setPredicate:predicate];

这就是我如何解决“每个位置/部分只有2个”部分的方法:

- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
    id <NSFetchedResultsSectionInfo> sectionInfo = [[self.fetchedResultsController sections] objectAtIndex:section];
    if (selectedTime == nil)
    {
        return [sectionInfo numberOfObjects];
    }
    else
    {
        if ([sectionInfo numberOfObjects] > 2)
        {
            return 2;
        }
        else
        {
            return [sectionInfo numberOfObjects];
        }
    }
}

感谢您的尝试,安德烈!

Duh.. I think I found the final solution ..

The fetch is pretty simple:

NSEntityDescription *entity = [NSEntityDescription 
                               entityForName:@"Performance" inManagedObjectContext:self.managedObjectContext];
[fetchRequest setEntity:entity];

NSSortDescriptor *sort1 = [[NSSortDescriptor alloc] 
                          initWithKey:@"location.name_extern" ascending:YES];
NSSortDescriptor *sort2 = [[NSSortDescriptor alloc] 
                           initWithKey:@"start" ascending:YES];
[fetchRequest setSortDescriptors:[NSArray arrayWithObjects:sort1,sort2,nil]];

[fetchRequest setFetchBatchSize:20];

NSFetchedResultsController *theFetchedResultsController = 
[[NSFetchedResultsController alloc] initWithFetchRequest:fetchRequest 
                                    managedObjectContext:self.managedObjectContext 
                                      sectionNameKeyPath:@"location.name_extern" 
                                               cacheName:nil];

With the following predicate:

NSPredicate *predicate = [NSPredicate predicateWithFormat:@"end > %@",selectedTime];

[fetchRequest setPredicate:predicate];

And here's how I solved the "only 2 per location/section" part:

- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
    id <NSFetchedResultsSectionInfo> sectionInfo = [[self.fetchedResultsController sections] objectAtIndex:section];
    if (selectedTime == nil)
    {
        return [sectionInfo numberOfObjects];
    }
    else
    {
        if ([sectionInfo numberOfObjects] > 2)
        {
            return 2;
        }
        else
        {
            return [sectionInfo numberOfObjects];
        }
    }
}

Thanks for trying though André!

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文