Урок 37. Запросы из связанных таблиц. INNER JOIN в SQLite. Метод rawQuery.

Обсуждение уроков
Аватара пользователя
damager82
Администратор
Сообщения: 1383
Зарегистрирован: 07 янв 2012, 11:32
Контактная информация:

Урок 37. Запросы из связанных таблиц. INNER JOIN в SQLite. Метод rawQuery.

Сообщение damager82 » 28 ноя 2011, 03:00

В этом уроке:

- читаем данные из связанных таблиц
- используем rawQuery

Click here to read this article!
Последний раз редактировалось damager82 01 май 2017, 16:41, всего редактировалось 5 раз.
Добро пожаловать на форум сайта StartAndroid
ИзображениеИзображение

pantomimo
Сообщения: 2
Зарегистрирован: 10 янв 2012, 11:53

Re: Урок 37. Запросы из связанных таблиц. INNER JOIN в SQLit

Сообщение pantomimo » 10 янв 2012, 12:00

Здравствуйте!
такой вопрос.

Вы закрываете базу dbh.close(); а нужно ли закрывать db.close(); ???

Спасибо!

Аватара пользователя
damager82
Администратор
Сообщения: 1383
Зарегистрирован: 07 янв 2012, 11:32
Контактная информация:

Re: Урок 37. Запросы из связанных таблиц. INNER JOIN в SQLit

Сообщение damager82 » 10 янв 2012, 12:10

pantomimo писал(а):Вы закрываете базу dbh.close(); а нужно ли закрывать db.close(); ???
Добрый день!
В dbh.close() уже выполняется db.close(), поэтому не нужно. Посмотрите следующий урок №38, там в конце я это расписал с примером.
Добро пожаловать на форум сайта StartAndroid
ИзображениеИзображение

pantomimo
Сообщения: 2
Зарегистрирован: 10 янв 2012, 11:53

Re: Урок 37. Запросы из связанных таблиц. INNER JOIN в SQLit

Сообщение pantomimo » 10 янв 2012, 13:17

damager82 писал(а):
pantomimo писал(а):Вы закрываете базу dbh.close(); а нужно ли закрывать db.close(); ???
Добрый день!
В dbh.close() уже выполняется db.close(), поэтому не нужно. Посмотрите следующий урок №38, там в конце я это расписал с примером.
спасибо! все отлично расписано! чуть поспешил с вопросом...)

irukanji
Сообщения: 12
Зарегистрирован: 26 мар 2012, 12:51

Re: Урок 37. Запросы из связанных таблиц. INNER JOIN в SQLit

Сообщение irukanji » 26 мар 2012, 13:03

Спасибо огромное за уроки... Если есть возможность у вас, не могли бы вы поподробнее остановиться на обьяснении как составлять SQL-запросы, а именно что все это значит --->

String sqlQuery = "select PL.name as Name, PS.name as Position, salary as Salary "
+ "from people as PL "
+ "inner join position as PS "
+ "on PL.posid = PS.id "
+ "where salary > ?";
или где можно об этом почитать? Спасибо.

яфпкк
Сообщения: 8
Зарегистрирован: 21 фев 2012, 05:59

Re: Урок 37. Запросы из связанных таблиц. INNER JOIN в SQLit

Сообщение яфпкк » 26 мар 2012, 14:13

ссылка на официальный ман
ну а вообще то, что ты спрашиваешь, не имеет прямого отношения к андроиду. Берешь любую документацию по sql на русском языке и читаешь, синтаксис очень похож

Аватара пользователя
damager82
Администратор
Сообщения: 1383
Зарегистрирован: 07 янв 2012, 11:32
Контактная информация:

Re: Урок 37. Запросы из связанных таблиц. INNER JOIN в SQLit

Сообщение damager82 » 26 мар 2012, 17:02

На Java, SQL и прочие используемые технологии я стараюсь не отвлекаться. Все таки сайт посвящен андроиду, по которому мало ресурсов в рунете.

Вам, действительно, имеет смысл поискать в сети SQL учебник какой-нибудь. Там для первого знакомства хватит одного дня. Например можно использовать этот: http://www.cs.ifmo.ru/education/documen ... ndex.shtml

Если разбирать текущий фрагмент:
"select PL.name as Name, PS.name as Position, salary as Salary "
+ "from people as PL "
+ "inner join position as PS "
+ "on PL.posid = PS.id "
+ "where salary > ?";
Здесь мы таблице people даем псевдоним PL (2-я строка), а таблице position - псевдоним PS (3-я строка). Это нужно просто для уменьшения кол-ва букв.
Во второй и третьей строке мы говорим, что хотим связать две таблицы и использовать данные из обоих (from и inner join). Связывать будем по условию в 4-й строке. И должно учитываться, что salary (5-я строка) больше параметра, который мы укажем далее. В итоге на выходе мы получим имя человека (PL.name), наименование должности (PS.name) и зарплату (salary) - это все мы указываем в первой строке (select).
В отличие от name здесь salary используется без PL. или PS., потому что оно только в одной из таблиц и система сама его найдет.
Добро пожаловать на форум сайта StartAndroid
ИзображениеИзображение

Аватара пользователя
KamiSempai
Сообщения: 1339
Зарегистрирован: 17 фев 2012, 21:23
Откуда: Мордор

Re: Урок 37. Запросы из связанных таблиц. INNER JOIN в SQLit

Сообщение KamiSempai » 26 мар 2012, 17:32

яфпкк писал(а):...синтаксис очень похож
Как человек продолжительное время программировавший под MS SQL, могу сказать, что похож он не везде. Я был приятно удивлен, когда SELECT TOP 1... почему-то не захотел работать. :)
А вот ссылка на оф.сайт действительно полезная штука. Только боюсь поможет она, если есть хоть какие то познания в SQL.
R.id.team
Хватит таскать макулатуру на тренировку! Используй T Note.

irukanji
Сообщения: 12
Зарегистрирован: 26 мар 2012, 12:51

Re: Урок 37. Запросы из связанных таблиц. INNER JOIN в SQLit

Сообщение irukanji » 26 мар 2012, 21:04

damager82 писал(а):На Java, SQL и прочие используемые технологии я стараюсь не отвлекаться. Все таки сайт посвящен андроиду, по которому мало ресурсов в рунете.

Вам, действительно, имеет смысл поискать в сети SQL учебник какой-нибудь. Там для первого знакомства хватит одного дня. Например можно использовать этот: http://www.cs.ifmo.ru/education/documen ... ndex.shtml

Если разбирать текущий фрагмент:
"select PL.name as Name, PS.name as Position, salary as Salary "
+ "from people as PL "
+ "inner join position as PS "
+ "on PL.posid = PS.id "
+ "where salary > ?";
Здесь мы таблице people даем псевдоним PL (2-я строка), а таблице position - псевдоним PS (3-я строка). Это нужно просто для уменьшения кол-ва букв.
Во второй и третьей строке мы говорим, что хотим связать две таблицы и использовать данные из обоих (from и inner join). Связывать будем по условию в 4-й строке. И должно учитываться, что salary (5-я строка) больше параметра, который мы укажем далее. В итоге на выходе мы получим имя человека (PL.name), наименование должности (PS.name) и зарплату (salary) - это все мы указываем в первой строке (select).
В отличие от name здесь salary используется без PL. или PS., потому что оно только в одной из таблиц и система сама его найдет.
Спасибо за ответ... Был далек от SQL теперь пришлось нырнуть...

яфпкк
Сообщения: 8
Зарегистрирован: 21 фев 2012, 05:59

Re: Урок 37. Запросы из связанных таблиц. INNER JOIN в SQLit

Сообщение яфпкк » 27 мар 2012, 06:34

KamiSempai писал(а):SELECT TOP 1... почему-то не захотел работать. :)
это наверное единственное отличие в синтаксисе (имею ввиду обычные селекты), не знаю как в sqlite, но в mysql это записывается так
select * from table1 limit 10, например

icamys
Сообщения: 22
Зарегистрирован: 07 май 2012, 00:32

Re: Урок 37. Запросы из связанных таблиц. INNER JOIN в SQLit

Сообщение icamys » 17 май 2012, 23:53

Сам столкнулся с трудностями в изучении последних глав, связанных с БД. После прочтения пятой главы книги "Using SQLite 2010" Jay Kreibich все разъяснилось. У кого тоже были трудности, очень советую почитать вышеупомянутую главу из книги.

Andy_NTG
Сообщения: 6
Зарегистрирован: 29 мар 2012, 12:06

Re: Урок 37. Запросы из связанных таблиц. INNER JOIN в SQLit

Сообщение Andy_NTG » 22 май 2012, 15:06

Как в rawQuery использовать множественные условия в WHERE?

String selection = "SELECT * FROM TABLE WHERE id=? AND data=? AND text=?
String[] selectionArgs = { id, data, text};

Cursor c = db.rawQuery(selection, selectionArgs);

Вот так не работает почему-то. Даже если selection заменить явно на строку

SELECT * FROM TABLE WHERE id='123' AND data='123'

а вторым агрументом указать null, то происходит то же самое. В SQLite нельзя использовать AND разве?

Аватара пользователя
damager82
Администратор
Сообщения: 1383
Зарегистрирован: 07 янв 2012, 11:32
Контактная информация:

Re: Урок 37. Запросы из связанных таблиц. INNER JOIN в SQLit

Сообщение damager82 » 23 май 2012, 09:32

Andy_NTG писал(а):В SQLite нельзя использовать AND разве?
Должно работать. Скорее всего выборка по таким условиям действительно ничего не возвращает. Проверьте данные в таблице.
Если указываете where с одним аргументом то работает?
Добро пожаловать на форум сайта StartAndroid
ИзображениеИзображение

Аватара пользователя
KamiSempai
Сообщения: 1339
Зарегистрирован: 17 фев 2012, 21:23
Откуда: Мордор

Re: Урок 37. Запросы из связанных таблиц. INNER JOIN в SQLit

Сообщение KamiSempai » 23 май 2012, 11:47

id и data какого типа? Если числового, кавычки нужно убрать.
R.id.team
Хватит таскать макулатуру на тренировку! Используй T Note.

Andy_NTG
Сообщения: 6
Зарегистрирован: 29 мар 2012, 12:06

Re: Урок 37. Запросы из связанных таблиц. INNER JOIN в SQLit

Сообщение Andy_NTG » 23 май 2012, 13:41

Да, всё работает, где-то в синтаксисе была ошибка.

Но вот есть новая проблема. SQLite не поддерживает поля календарного, так сказать, типа. То есть сортировку по дате не сделать, получается. Пробую сохранать в базу значения типа YYYY-MM-DD HH:MM:SS.SSS, но по ним почему-то не происходит корректная сортировка.

P.S. Перевёл в поле типа int и записал туда время в миллисекундах. Теперь сортировка работает.

Аватара пользователя
KamiSempai
Сообщения: 1339
Зарегистрирован: 17 фев 2012, 21:23
Откуда: Мордор

Re: Урок 37. Запросы из связанных таблиц. INNER JOIN в SQLit

Сообщение KamiSempai » 24 май 2012, 16:57

Andy_NTG писал(а):Но вот есть новая проблема. SQLite не поддерживает поля календарного, так сказать, типа. То есть сортировку по дате не сделать, получается. Пробую сохранать в базу значения типа YYYY-MM-DD HH:MM:SS.SSS, но по ним почему-то не происходит корректная сортировка.

P.S. Перевёл в поле типа int и записал туда время в миллисекундах. Теперь сортировка работает.
Не может быть такого. Сам использую вышеописанный формат даты, только без милисекунд, и все отлично сортируется. Каким образом Вы переводите дату в строку?
R.id.team
Хватит таскать макулатуру на тренировку! Используй T Note.

beeline09
Сообщения: 33
Зарегистрирован: 23 сен 2012, 23:10

Re: Урок 37. Запросы из связанных таблиц. INNER JOIN в SQLit

Сообщение beeline09 » 07 мар 2013, 16:47

Добрый день всем! Есть проблема. Бьюсь уже три дня и не могу понять в чем дело...
В общем, есть база у меня data.db. В ней есть куча таблиц (база не моя, а готовая с инета).
Мне нужна таблица food, в которой есть столбцы "id, title, proteins, fats, carbohydrates, water, energy". Это не все столбцы, но мне нужны только эти.
Мне нужно организовать поиск по строкам столбца title. Идея такая. Ввожу в edittext часть слова или слово, которое хочу найти. Нажимаю на баттон и нижу мой listview должен заполниться строками из "title, proteins, fats, carbohydrates, water, energy", в которых titlе равен или содержит текст из edittext-а.
Делал такой запрос:

Код: Выделить всё

EditText search_prod = (EditText) findViewById(R.id.et_dob_prod);
				lv_product = (ListView) findViewById(R.id.lv_dob_prod);
				String[] arrayOfString = new String[1];
		        arrayOfString[0] = String.valueOf(search_prod.getText().toString());
				try {
					
					String [] selectionArgs = {search_prod.getText().toString() + "%"};
					Cursor cursor;
					// Wrap the next line in try-catch
					cursor = database.rawQuery("select title, proteins, fats, carbohydrates, water, energy from food where food.title = ?", arrayOfString);
					
				if (cursor.moveToFirst()) {
					do {
						Toast.makeText(getApplicationContext(), cursor.getString(0), Toast.LENGTH_LONG).show();
						// list1.add(cursor.getString(0));
						RowItemProduct item2 = new RowItemProduct(
								R.drawable.dieta, cursor.getString(0), cursor
										.getString(1), cursor.getString(2),
								cursor.getString(3), cursor.getString(5));

						rowItems_product.add(item2);

					} while (cursor.moveToNext());
				}
				if (cursor != null && !cursor.isClosed()) {
					cursor.close();
				}
				}catch (Exception e) {
					// TODO: handle exception
					Log.d(LOG_TAG, e.toString());
				}

				rowItems_product = new ArrayList<RowItemProduct>();

				CustomLVAdapterProduct adapter1 = new CustomLVAdapterProduct(
						context, R.layout.list_item_product, rowItems_product);
				lv_product.setAdapter(adapter1);

			}
Но он не дает результатов... Уже не знаю, что и делать :-(
В БД я вообще нуб, но есть необходимость реализовать. Когда-то в университете имел дело с access в делфи, но там другое и уже много забыл...
Вот скрин структуры базы:
Скрин базы на компе
Скрин базы на компе
ScreenShot2222.png (68.26 КБ) 15930 просмотров
Пожалуйста помогите мне. Я перерыл весь интернет, перепробовал кучу вариантов, но ничего не выходит :-(

Аватара пользователя
Foenix
Сообщения: 4201
Зарегистрирован: 20 окт 2012, 12:01

Re: Урок 37. Запросы из связанных таблиц. INNER JOIN в SQLit

Сообщение Foenix » 08 мар 2013, 00:29

Знак процента можно с обоих сторон добавлять.
Второе, тут поиск с русскими буквами будет глючить. Я видела такую реализацию. В таблицу заносят данные, и еще делают столбик с данными только большими буквами. И ищут по нему, предварительно приведя и строку в большие буквы.
Другой способ - ищи в интернете, сильно заморочистый, чтоб подружить sqlite с русскими буквами.
Хотя что значит у тебя "не ищет". Вообще ничего не выдает, что ли?
распечатй запрос в лог, возьми базу, какой-нибудь редактор, открой ее там, внеси запрос из лога и посмотри что выдается. Тестировать запросы луше так.
R.id.team

NullPointerException - что делать???
viewtopic.php?f=33&t=3899&p=28952#p28952
Где моя ошибка?
viewtopic.php?f=60&t=3198

Аватара пользователя
Foenix
Сообщения: 4201
Зарегистрирован: 20 окт 2012, 12:01

Re: Урок 37. Запросы из связанных таблиц. INNER JOIN в SQLit

Сообщение Foenix » 08 мар 2013, 00:31

и кстати, нужно писать не знак равенства в запросе, а оператор LIKE.
Равенство нормально работает с любыми буквами вроде, но так в результатах запроса у тебя вряд ли что-то будет.
R.id.team

NullPointerException - что делать???
viewtopic.php?f=33&t=3899&p=28952#p28952
Где моя ошибка?
viewtopic.php?f=60&t=3198

beeline09
Сообщения: 33
Зарегистрирован: 23 сен 2012, 23:10

Re: Урок 37. Запросы из связанных таблиц. INNER JOIN в SQLit

Сообщение beeline09 » 08 мар 2013, 09:25

Olivka писал(а):Знак процента можно с обоих сторон добавлять.
Второе, тут поиск с русскими буквами будет глючить. Я видела такую реализацию. В таблицу заносят данные, и еще делают столбик с данными только большими буквами. И ищут по нему, предварительно приведя и строку в большие буквы.
Другой способ - ищи в интернете, сильно заморочистый, чтоб подружить sqlite с русскими буквами.
Хотя что значит у тебя "не ищет". Вообще ничего не выдает, что ли?
распечатй запрос в лог, возьми базу, какой-нибудь редактор, открой ее там, внеси запрос из лога и посмотри что выдается. Тестировать запросы луше так.

и кстати, нужно писать не знак равенства в запросе, а оператор LIKE.
Равенство нормально работает с любыми буквами вроде, но так в результатах запроса у тебя вряд ли что-то будет.
Сделал вот так:

Код: Выделить всё

cursor = database.rawQuery("SELECT title, proteins, fats, carbohydrates, water, energy FROM food WHERE food.title LIKE ?", arrayOfString);
Когда ввожу с большой буквы, то в listview у меня появляется один результат, в котором title четко совпадает с текстом из edittext. Ну с регистром букв, я думаю, уже реальнее разобраться. Но вот я хочу, чтоб поиск был не по началу названия, а по всей строке из title чтоб искалось наличие текста из edittext. Такое реально вообще сделать? Я видел подобную реализацию в приложении Диетический калькулятор, но к сожалению исходников нет нигде... Вы мне можете подсказать, что сделать? Как сделать такой запрос, который выдаст не строго строчку, а строчку в которой присутствует нужный текст?

UPD1: Проблема решена! Спасибо за подсказку на счет процента! Сделал вот так :

Код: Выделить всё

arrayOfString[0] = String.valueOf("%"+search_prod.getText().toString()+"%");
и начало искать все совпадения! Круто! ))) Теперь буду искать на счет регистронезависимого поиска. Если есть идеи, то и тут попрошу помощи :-)

UPD2: Поиск по интернету не дал результатов. Решил сам попробовать. В итоге решил сделать два запроса к базе. Один начинается с большой буквы, второй - с маленькой. База достаточно большая, но на нагрузке устройства это не сказывается. Может кому пригодится в будущем. Вот реализация:

Код: Выделить всё

EditText search_prod = (EditText) findViewById(R.id.et_dob_prod);
lv_product = (ListView) findViewById(R.id.lv_dob_prod);
String[] arrayOfString = new String[1];
String[] arrayOfString1 = new String[1];
String verh_registr = search_prod.getText().toString();
verh_registr = verh_registr.substring(0, 1).toUpperCase()+verh_registr.substring(1);
String nizh_registr = verh_registr;
nizh_registr = nizh_registr.substring(0, 1).toLowerCase()+nizh_registr.substring(1);
arrayOfString[0] = String.valueOf("%"+verh_registr+"%");
arrayOfString1[0] = String.valueOf("%"+nizh_registr+"%");
Cursor cursor;
Cursor cursor1;
rowItems_product = new ArrayList<RowItemProduct>();	
cursor = database.rawQuery("SELECT title, proteins, fats, carbohydrates, water, energy FROM food WHERE food.title LIKE ?", arrayOfString);
cursor1 = database.rawQuery("SELECT title, proteins, fats, carbohydrates, water, energy FROM food WHERE food.title LIKE ?", arrayOfString1);

cursor.moveToFirst();
while (!cursor.isAfterLast()) {
       	RowItemProduct item2 = new RowItemProduct(R.drawable.dieta, cursor.getString(0), cursor.getString(1), cursor.getString(2), cursor.getString(3), cursor.getString(5));
       	rowItems_product.add(item2);
	cursor.moveToNext();
					}
cursor1.moveToFirst();
while (!cursor1.isAfterLast()) {
	RowItemProduct item21 = new RowItemProduct(R.drawable.dieta, cursor1.getString(0), cursor1.getString(1), cursor1.getString(2), cursor1.getString(3), cursor1.getString(5));
	rowItems_product.add(item21);
	cursor1.moveToNext();
					}
CustomLVAdapterProduct adapter1 = new CustomLVAdapterProduct(context, R.layout.list_item_product, rowItems_product);
lv_product.setAdapter(adapter1);
Всем, кто помогал большое спасибо! Надеюсь данная реализация пригодится в будущем таким же постигающим данный путь как и я :-D

Ответить