Android SQLite "порядок по" вычисляемый столбец в запросе объединения - PullRequest
0 голосов
/ 02 января 2011

Я использовал следующий код для запроса одной таблицы:

public Cursor fetchFilteredItemsNearSortedByDistance(String strTable, String[] strArrayFields, String strField, String strCriterion, double dblCentreEasting, double dblCentreNorthing, double dblRadius) {

  String strSQL = "Easting > " + Double.toString(dblCentreEasting-dblRadius);
  strSQL += " AND Easting < "  + Double.toString(dblCentreEasting+dblRadius);
  strSQL += " AND Northing > "  + Double.toString(dblCentreNorthing-dblRadius);
  strSQL += " AND Northing < "  + Double.toString(dblCentreNorthing+dblRadius);
  strSQL += " AND " + strField + " LIKE '%" + strCriterion + "%'";
  strSQL += " ORDER BY ";
  strSQL += "((Easting - " + Double.toString(dblCentreEasting)+")";
  strSQL += " * (Easting - " + Double.toString(dblCentreEasting)+")";
  strSQL += " + (Northing - " + Double.toString(dblCentreNorthing)+")";
  strSQL += " * (Northing - " + Double.toString(dblCentreNorthing)+"))";
  strSQL += " COLLATE NOCASE";

  return myDbHelper.myDataBase.query(strTable, strExtendedArrayFields, strSQL, null, null, null, null);     
}

Приведенный выше код работал удовлетворительно.Тем не менее, теперь я хочу распространить идею на UNION из двух или более таблиц, и попробовал следующий код:

public Cursor fetchFilteredPOIsNearSortedByDistance(String strTable, String[] strArrayFields, String strField, String strCriterion, double dblCentreEasting, double dblCentreNorthing, double dblRadius) {

  String strSQL = "SELECT * FROM TableA ";
  strSQL += "UNION SELECT * FROM TableB ";
  strSQL += "WHERE ( Easting > " + Double.toString(dblCentreEasting-dblRadius);
  strSQL += " AND Easting < "  + Double.toString(dblCentreEasting+dblRadius);
  strSQL += " AND Northing > "  + Double.toString(dblCentreNorthing-dblRadius);
  strSQL += " AND Northing < "  + Double.toString(dblCentreNorthing+dblRadius);
  strSQL += " AND " + strField + " LIKE '%" + strCriterion + "%' ) ";
  strSQL += " ORDER BY ";
  strSQL += "((Easting - " + Double.toString(dblCentreEasting)+")";
  strSQL += " * (Easting - " + Double.toString(dblCentreEasting)+")";
  strSQL += " + (Northing - " + Double.toString(dblCentreNorthing)+")";
  strSQL += " * (Northing - " + Double.toString(dblCentreNorthing)+"))";
  strSQL += " COLLATE NOCASE";

  return myDbHelper.myDataBase.rawQuery(strSQL, null);
}

Однако, это создает «SQLiteException: 1-й термин ORDER BY не соответствует ни одномустолбец в наборе результатов "ошибка.

Полная ошибка в LogCat:

ERROR/AndroidRuntime(11444): Caused by: android.database.sqlite.SQLiteException: 1st ORDER BY term does not match any column in the result set: , while compiling: SELECT * FROM TableA UNION SELECT * FROM TableB WHERE ( Easting > 594378.8427734375 AND Easting < 663822.8427734375 AND Northing > 127586.046875 AND Northing < 197030.046875 AND Name LIKE '%%' )  ORDER BY ((Easting - 629100.8427734375) * (Easting - 629100.8427734375) + (Northing - 162308.046875) * (Northing - 162308.046875)) COLLATE NOCASE

Может кто-нибудь помочь мне на правильном пути, пожалуйста?

Ответы [ 3 ]

2 голосов
/ 02 января 2011

Полное предположение (я не знаком с Android SQLLite, но являюсь другими движками БД): если вы помещаете результат своего объединения в подзапрос, а затем выбираете * из подзапроса и упорядочиваете эти результаты, это работает? Примерно так (с вашими столбцами / таблицами / и т. Д.), Если бы я был в SQL Server:

SELECT tblResults.* FROM
    (SELECT X FROM tblA
     UNION
     SELECT X FROM tblB) AS tblResults
ORDER BY tblResults.X
1 голос
/ 03 января 2011

Я думаю, что я допустил некоторые ошибки в синтаксисе моего SQL.

Проще говоря, код, который не работал, был:

SELECT * FROM TableA UNION SELECT * FROM TableB
WHERE (FieldA > X1 AND FieldA < X2 AND FieldB > Y1 AND FieldB < Y2
AND FieldC LIKE '%Criterion%')
ORDER BY [Function of FieldA and FieldB] COLLATE NOCASE

Я заменил этоwith:

SELECT FieldA, FieldB, FieldC, .... ,
[Function of FieldA and FieldB] AS CalculatedField
FROM TableA
WHERE FieldA BETWEEN X1 AND X2
AND FieldB BETWEEN Y1 AND Y2
AND FieldC LIKE '%Criterion%'
UNION
SELECT FieldA, FieldB, FieldC, .... ,
[Function of FieldA and FieldB] AS CalculatedField
FROM TableB
WHERE FieldA BETWEEN X1 AND X2
AND FieldB BETWEEN Y1 AND Y2
AND FieldC LIKE '%Criterion%'
ORDER BY CalculatedField COLLATE NOCASE

Хотя этот оператор SQL намного длиннее, он, кажется, работает, и что удивительно быстро ... фильтрация примерно 10000 строк данных и сортировка всего происходит менее чем за 50миллисекунды.

0 голосов
/ 03 января 2011

просто несколько быстрых комментариев,

  1. Вместо использования > и < попробуйте использовать инструкцию SQL Between
  2. Вы должны потратить время на создание пользовательской функции SQLite для возврата элементов внутри радиуса, это будет лучше и с меньшими изменениями запутывает запрос. Просто Google SQLite custom functions
...