Да. Я обычно рекомендую людям думать об этом, как будто JOIN
действует так же, как открывающая скобка (
, а ON
действует так же, как закрывающая скобка )
. Тогда обычные правила, которые вы использовали для сопоставления скобок, сообщают вам , какое предложение ON
относится к , который JOIN
, и дает вам некоторый контекст для определения, какие имена / псевдонимы таблиц находятся в области.
Таким образом, этот запрос эффективно объединяет таблицу B
с таблицей C
, а затем соединяет A
с , что объединяет результат.
Обычно я рекомендовал бы против этого, когда просто использовал INNER JOIN
s - вы можете легко переставить таблицы так, чтобы следовать более «нормальному» паттерну JOIN
/ ON
/ JOIN
/ ON
. Вы получите тот же логический результат из этого запроса 1 sup>:
SELECT *
FROM Table_B B
INNER JOIN Table_C C
ON C.Id = B.Id
INNER JOIN Table_A A
ON B.Id = A.Id
Обратите внимание, что этот описан в документации , если вы внимательно прочитали:
blockquote>
::= { table_or_view_name [ [ AS ] table_alias ] [ ] [ WITH ( < table_hint > [ [ , ]...n ] ) ] ... | ... И
blockquote>
::= { ON ... Итак, в
что идет слева от
? Любой
. А что идет справа от
? Любой
. И один из них или оба могут сами по себе быть
.
«Нормальная» форма, на которую вы ссылаетесь в своем вопросе, - это то, что выпадает, если мы только позволим себе использовать
в левой позиции другого
.
1 sup> Хотя если вы полагаетесь на порядок столбцов , а не на имена столбцов , столбцы будут в другом порядке из-за использования
SELECT *
. Но вы не должны полагаться на порядки столбцов.
Это собирается звучать немым, но... мм... "расположение Ваша ячейка перед выходом из heightForRowAtIndexPath" ;)
Серьезно, хотя - ОС только когда-либо называет это, если это будет необходимым (как в: это собирается создать ячейку и отобразить его на экране), таким образом размечая его, и подготовка отобразиться не является потраченным впустую усилием.
Отметьте, Вы не должны делать своего расположения отдельно, логически-мудрый. Просто позвоните Вашему [сам prepLayoutForCellAtIndex:index] в Вашей heightForRowAtIndexPath стандартной программе.
Если данные статичны, можно составить таблицу высоты и кэшировать информацию.
if (0 == heightTable[index]) {
heightTable[index] = [self prepLayoutForCellAtIndex:index];
}
return (heightTable[index]);
Heck, даже если данные изменяются, можно или повторно вычислить значение таблицы в методе, который изменяет данные, или ясный 0, таким образом, это повторно вычисляется в следующий раз, когда это необходимо.
Я использую следующее, обычно:
- (CGFloat) tableView:(UITableView *)tableView heightForRowAtIndexPath: (NSIndexPath *) indexPath {
UITableViewCell *cell = [self tableView: tableView cellForRowAtIndexPath: indexPath];
return cell.bounds.size.height;
}
Обратите внимание, что я использую это для таблиц, где я предварительно кэширую набор строк заранее, не для тех, которые имеют МНОГО ячеек. Однако для вещей как таблицы Settings, где существует всего несколько строк, но скорее всего очень по-другому измеренный, это работает хорошо. Для больших таблиц я делаю что-то вроде какой предложенный Olie.
При рассмотрении SMS.app как примера Apple сохраняет высоту строки ячейки в SMS.app sqlite база данных.