SQLITE случайное значение / строка с критериями - PullRequest
0 голосов
/ 27 августа 2018

Итак, я знаю, что вопрос о получении случайной строки в базе данных SQL был опубликован (даже более одного раза), и он помог мне добраться до этого запроса SQL:

"SELECT column FROM table WHERE id IN (SELECT id FROM table ORDER BY RANDOM() LIMIT 1)"; 

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

Итак, я попробовал, кажется, что это работает хорошо, но затем я хотел добавить критерий, поэтому я немного его изменил:

"SELECT column1 FROM table WHERE (column2 LIKE '" + value + "' AND id IN (SELECT id FROM table ORDER BY RANDOM() LIMIT 1)"; 

Чтобы быть более понятным, у меня есть эта таблица: загружен = (идентификатор, имя файла, владелец). Я хочу выбрать случайное имя файла от данного владельца. Что дает мне это:

"SELECT filename FROM uploaded WHERE (owner LIKE '" + owner + "' AND id IN (SELECT id FROM uploaded ORDER BY RANDOM() LIMIT 1))";

Проблема в том, что иногда rs.next ложен (что означает, что у меня нет результата). Тем не менее, я печатаю БД перед поиском имени файла, поэтому я уверен, что владелец имеет связанное имя файла в этой БД. Может быть только один, но все еще один.

Это подводит меня к вопросу: что не так с моим запросом?

Ответы [ 2 ]

0 голосов
/ 27 августа 2018

Вы хотите получить случайный идентификатор для owner, а не любой идентификатор. Вот почему вы иногда получаете пустой результат. Вы получаете идентификатор, который не для OWNER, поэтому оба условия не ИСТИНА.

Поэтому добавьте условие в этот запрос:

SELECT id FROM uploaded where owner = ? ORDER BY RANDOM() LIMIT 1

Нет необходимости дважды проверять owner, у вас уже есть id для него. Итак:

SELECT filename FROM uploaded WHERE id IN (
    SELECT id FROM uploaded where owner LIKE ? ORDER BY RANDOM() LIMIT 1
)

PS: используется нотация PreparedStatement.

PreparedStatement stmt = conn.prepareStatement(query);
stmt.setString(1, owner);
ResultSet rs = stmt.executeQuery();

Я предлагаю вам проверить его, чтобы предотвратить SQL-инъекцию , или вы можете заменить ? на String.

0 голосов
/ 27 августа 2018

Проблема в том, что вы выбираете случайную строку, а затем проверяете, что столбец имеет определенное значение. Вы должны сделать это наоборот, поместив предложение WHERE на внутреннюю команду select:

"SELECT filename " +
"FROM uploaded " +
"WHERE id in " +
"  (SELECT id " +
"   FROM uploaded " +
"   WHERE owner LIKE ? " +
"   ORDER BY RANDOM() LIMIT 1)";

Обратите внимание, что я использую ? вместо конкатенации владельца непосредственно в запросе. Вы должны передать правильное значение в качестве параметра правильной функции SQLite. Этот параметр называется связанным параметром и гарантирует защиту от внедрения SQL.

...