ВНУТРЕННЕЕ СОЕДИНЕНИЕ или вложенный ВЫБОР в этом случае?

#sql #sqlite #join #inner-join

#sql #sqlite #Присоединиться #внутреннее соединение

Вопрос:

У меня есть две таблицы:

 atvtrails_prim:

ID int PK
ID2 int
TType varchar(100)

atvtrails_sec:

ID2 int Foreign Key(Relates to ID2 of atvtrails_prim)
Latitude double
Longitude double
  

Что я хочу от этих таблиц: все записи в atvtrails_sec, ID2 которых имеет определенный TType в atvtrails_prim.

Запрос, который я использую (вложенный ВЫБОР):

 SELECT atvtrails_sec.ID2,atvtrails_sec.Latitude, atvtrails_sec.Longitude,atvtrails_prim.TType 
FROM atvtrails_sec,atvtrails_prim 
WHERE atvtrails_sec.Latitude BETWEEN %@ and %@ 
AND atvtrails_sec.Longitude BETWEEN %@ and %@ 
AND (
    SELECT TType from atvtrails_prim where ID2=atvtrails_sec.ID2
    ) =%@", lrLat, ulLat, lrLong, ulLong,type2
  

Lrl L, ulLat, lrLong, ulLong, type2 являются переменными. Я пишу на objective-c.

Этот запрос дает мне очень большой набор данных. Это дает мне правильные, но они дублируются. Я получаю около 90000 результатов, в то время как в таблице всего 18000 записей. Этот запрос занимает много времени, когда я проводил измерения, и мне нужно более быстрое решение.

Запрос, который я использую (ВНУТРЕННЕЕ СОЕДИНЕНИЕ):

 SELECT atvtrails_sec.ID2,atvtrails_sec.Latitude, atvtrails_sec.Longitude 
FROM atvtrails_sec 
INNER JOIN atvtrails_prim ON atvtrails_prim.TType=%@ 
WHERE atvtrails_sec.Latitude BETWEEN %@ and %@ 
AND atvtrails_sec.Longitude BETWEEN %@ and %@", lrLat, ulLat, lrLong, ulLong,type1
  

Это не возвращает мне никаких данных. Я новичок в SQLite. Пожалуйста, подскажите мне, как я могу получить нужные данные с помощью Inner-Join. Кроме того, есть ли какой-либо способ оптимизировать мой вложенный запрос ВЫБОРА, чтобы он не давал мне дополнительных данных?

Комментарии:

1. Вы можете выделить сегменты кода в своем вопросе и щелкнуть {} значок, чтобы сохранить форматирование кода. Также попробуйте отформатировать код доступным для чтения способом. Наконец, используете ли вы mysql или sqlite? Удалите неподходящий тег.

2. Возникли проблемы с анализом ваших запросов, но не похоже, что вы когда-либо объединяли свои таблицы во втором запросе. Существует множество руководств, вот одно: Clicky

3. Здесь я использую SQLite.

Ответ №1:

Сработает ли что-то подобное?:

 SELECT prim.ID,sec.*
FROM atvtrails_prim prim
LEFT JOIN atvtrails_sec sec ON sec.ID2 = prim.ID2
WHERE prim.TType = 'dirt';
  

Кроме того, вы можете захотеть проиндексировать свой atvtrails_prim.Столбец TType для повышения производительности запроса:

 ALTER TABLE atvtrails_prim ADD KEY TType (TType );
  

Ответ №2:

Результаты становятся раздутыми, потому что вы забываете применить значимое предложение join. Объединение двух таблиц без предложения называется декартовым соединением и возвращает t1 * t2 строки, где t1 — количество строк в table1, а t2 — количество строк в t2.

Что касается значимого предложения join, в данном случае я имею в виду t1.ID2 = t2.ID2 предложение. Если это отношение внешнего ключа, это предложение гарантирует, что максимальное количество возвращаемых строк равно MAX (t1, t2).

Итак, начните свой запрос следующим образом и возьмите его оттуда:

 SELECT * FROM t1
INNER JOIN t2 ON t1.ID2 = t2.ID2
(...)
  

Комментарии:

1. «Объединение двух таблиц без предложения называется декартовым соединением и вернет t1 * t2 строки, где t1 — количество строк в table1, а t2 — количество строк в t2». 1