使用子查询

时间:2015-07-06 13:44:35

标签: sql sql-server

我正在使用三个表:RGN (region)FAC (facility)RGN_FAC。在最简单的形式,设施可以与多个地区相关联。这些关联存储在RGN_FAC表中。

每个区域都有一个名为PrimaryFlag的列。我正在尝试创建与给定设施关联的每个区域的PrimaryFlag值列表。我能够使用以下子查询执行此操作:

SELECT [dbo].[RGN].PRIMARY_FLAG
FROM [dbo].[RGN]
WHERE [dbo].[RGN].ID in

(SELECT [dbo].[RGN_FAC].RGN_ID
FROM [dbo].[RGN_FAC]
WHERE [dbo].[RGN_FAC].FAC_ID = 'my fac id')

有人告诉我,我可以使用连接而不是子查询更有效地完成此操作。但是,我不知道如何通过加入来实现这一目标。

3 个答案:

答案 0 :(得分:1)

cell.contentView

可能会删除- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath { static NSString *cellIdentifier = @"SelectBookCell"; SelectBookCell *cell = [tableView dequeueReusableCellWithIdentifier:cellIdentifier]; if (cell == nil) { // this is wrong // cell = [[SelectBookCell alloc] init]; // -- // must be cell = [[SelectBookCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:cellIdentifier]; } ... // this statement looks correct but if you check it, it's not // try logging this: NSLog(@"Wrong: %@", (1 < (NSInteger)@"1") ? @"YES" : @"NO"); // this will return `YES` and that is wrong // if you try this: NSLog(@"Correct: %@", (1 < [@"1" intValue]) ? @"YES" : @"NO"); // it will log the correct one // your condition // `if([[userAccount level] intValue] <= (NSInteger)[book objectForKey:@"level"])` // was never true // try this is instead: if([[userAccount level] intValue] <= [[book objectForKey:@"level"] intValue]) { [cell setAlpha: 0.2f]; // or [cell.contentView setAlpha: 0.2f]; } else { // dont for get this else statement to avoid unwanted behaviour // on cell reuse [cell setAlpha:1.0f]; // or [cell.contentView setAlpha:1.0f]; } return cell; } ,具体取决于是否可能出现重复。

答案 1 :(得分:1)

实际上,SQL Server有一个非常好的优化器。但是,最好的方法通常是EXISTS

SELECT r.PRIMARY_FLAG
FROM [dbo].[RGN] r
WHERE EXISTS (SELECT 1
              FROM [dbo].[RGN_FAC] f
              WHERE f.FAC_ID = 'my fac id' AND r.id = f.RGN_ID
             );

严格等效JOIN将是:

SELECT r.PRIMARY_FLAG
FROM [dbo].[RGN] r JOIN
     (SELECT DISTINCT f.RGN_ID
      FROM [dbo].[RGN_FAC] f
      WHERE f.FAC_ID = 'my fac id' 
     ) f
     ON f.RGN_ID = r.id

但是,DISTINCT可能是性能问题。如果您知道子查询中的值永远不会重复,则可以将其删除:

SELECT r.PRIMARY_FLAG
FROM [dbo].[RGN] r JOIN
     (SELECT f.RGN_ID
      FROM [dbo].[RGN_FAC] f
      WHERE f.FAC_ID = 'my fac id' 
     ) f
     ON f.RGN_ID = r.id;

当然,如果你想要表现,那么通常索引会有所帮助。对于第一个查询:RGN_FAC(RGN_ID, FAC_ID)是最佳索引。对于使用JOININ的版本,您需要RGN_FAC(FAC_ID, RGN_ID)

答案 2 :(得分:0)

您需要使用INNER JOIN。这样可以确保只有[dbo].[RGN].PRIMARY_FLAG的匹配[dbo].[RGN_FAC].RGN_ID才能获得记录。

SELECT [dbo].[RGN].PRIMARY_FLAG
FROM [dbo].[RGN]
INNER JOIN [dbo].[RGN_FAC] on [dbo].[RGN_FAC].FAC_ID = 'my fac id' AND [dbo].[RGN].ID = [dbo].[RGN_FAC].RGN_ID

根据数据库的设置方式,您可以考虑将DISTINCT添加到SELECT以避免重复返回。

SELECT DISTINCT [dbo].[RGN].PRIMARY_FLAG
FROM [dbo].[RGN]
INNER JOIN [dbo].[RGN_FAC] on [dbo].[RGN_FAC].FAC_ID = 'my fac id' AND [dbo].[RGN].ID = [dbo].[RGN_FAC].RGN_ID