Почему мой запрос Inner Join ничего не возвращает? - PullRequest
0 голосов
/ 09 февраля 2019

У меня есть две таблицы тренировок и упражнений.Я пытаюсь получить все упражнения с идентификатором workout_id, который соответствует тренировке, на которую мы нажали.Я сделал запрос Inner Join, но он, похоже, ничего не возвращает.Что-то не так с моим запросом?

Я использую SQLite для создания своей базы данных.Я проверил, чтобы убедиться, что в таблице «Упражнения» есть упражнения, и у них есть workout_id.

Мой запрос:

    @Nullable
@Override
public Cursor query(@NonNull Uri uri, @Nullable String[] projection, @Nullable String selection, @Nullable String[] selectionArgs, @Nullable String sortOrder) {
    SQLiteDatabase db = dbHelper.getReadableDatabase();
    Cursor cursor = null;
    int match = uriMatcher.match(uri);
    switch (match){
        case WORKOUT:
            cursor = db.query(WorkoutContract.WorkoutEntry.TABLE_NAME_WORKOUT,projection,selection,selectionArgs,null,null,sortOrder);
            break;
        case WORKOUT_ID:
            selection = WorkoutContract.WorkoutEntry._ID + "=?";
            selectionArgs = new String[]{String.valueOf(ContentUris.parseId(uri))};
            cursor = db.query(WorkoutContract.WorkoutEntry.TABLE_NAME_WORKOUT,projection,selection,selectionArgs,null,null,sortOrder);
            break;
        case EXERCISE:
            cursor = db.query(WorkoutContract.WorkoutEntry.TABLE_NAME_EXERCISES,projection,selection,selectionArgs,null,null,sortOrder);
            break;
        case EXERCISE_ID:
            selection = WorkoutContract.WorkoutEntry._ID + "=?";
            selectionArgs = new String[]{String.valueOf(ContentUris.parseId(uri))};
            cursor = db.query(WorkoutContract.WorkoutEntry.TABLE_NAME_EXERCISES,projection,selection,selectionArgs,null,null,sortOrder);
            break;
        case WORkOUT_EXERCISE:
            final String QUERY = "SELECT workouts._id, " +
                    "exercise_name," +
                    "weight," +
                    "reps," +
                    "rpe"+
                    " FROM "+
                    "exercises"+
                    " INNER JOIN workouts ON workouts._id = exercises.workout_id"+
                    " WHERE workouts._id=1";
           cursor = db.rawQuery(QUERY, null);
            break;

        default:
            throw new IllegalArgumentException("Failed to retrieve" + uri);
    }
    cursor.setNotificationUri(getContext().getContentResolver(),uri);
    int rowcount = cursor.getCount();
    Log.d("ROWCOUNT","Number of rows = " + String.valueOf(rowcount));
    return cursor;    }

Мои таблицы:

String CREATE_TABLE_WORKOUTS = "CREATE TABLE " + WorkoutContract.WorkoutEntry.TABLE_NAME_WORKOUT + " ("
            + WorkoutContract.WorkoutEntry._ID + " INTEGER PRIMARY KEY, "
            + WorkoutContract.WorkoutEntry.WORKOUT_TITLE + " STRING, "
            + WorkoutContract.WorkoutEntry.WORKOUT_DATE + " STRING" + ")";

    String CREATE_TABLE_EXERCISES = "CREATE TABLE " + WorkoutContract.WorkoutEntry.TABLE_NAME_EXERCISES + " ("
            + WorkoutContract.WorkoutEntry._ID + " INTEGER PRIMARY KEY, "
            + WorkoutContract.WorkoutEntry.EXERCISE_NAME  + " STRING, "
            + WorkoutContract.WorkoutEntry.REPS + " INTEGER, "
            + WorkoutContract.WorkoutEntry.RPE + " INTEGER, "
            + WorkoutContract.WorkoutEntry.WEIGHT + " INTEGER, "
            + WorkoutContract.WorkoutEntry.WORKOUT_ID + " INTEGER, "
            + "FOREIGN KEY"+"("+ WorkoutContract.WorkoutEntry.WORKOUT_ID+")" + " REFERENCES "
            + WorkoutContract.WorkoutEntry.TABLE_NAME_WORKOUT
            +"("
            +(WorkoutContract.WorkoutEntry._ID) +")" +")";

Я ожидаю, что курсор вернет некоторые упражнения с соответствующим workout_id, но я, похоже, ничего не получу обратно.Никаких ошибок не возникает, просто пустой список.

ИСПРАВЛЕНО

1) Я указывал на неверный URI в MainActivity, поэтому я его изменил.

Uri uri = withAppendedId(WorkoutContract.WorkoutEntry.CONTENT_URI, id);

Uri uri = withAppendedId(WorkoutContract.WorkoutEntry.JOIN_TABLE_URI, id);

2) Назад внутрьмой класс WorkoutProvider Я установил selectionArgs:

 selectionArgs = new String[]{String.valueOf(ContentUris.parseId(uri))};

и передал это в мой rawQuery.

cursor = db.rawQuery(QUERY, selectionArgs);

1 Ответ

0 голосов
/ 09 февраля 2019

Ваша проблема в том, что вы фактически произносите ..... WHERE workouts._id = '_id', поскольку у вас есть selectionArgs = new String[]{String.valueOf(WorkoutContract.WorkoutEntry.WORKOUT_ID)};

и что WorkoutContract.WorkoutEntry.WORKOUT_ID - это имя столбца _id .

Поскольку такое совпадение для предложения WHERE никогда не будет выполнено, поскольку столбец _id ДОЛЖЕН быть целым числом (длинным в языке Java, так как он имеет до 64-битное целое число со знаком) в качестве столбца.это псевдоним rowid .

Вместо этого вам нужно иметь что-то вроде

selectionArgs = new String[]{String.valueOf(the_id_that_you_are_looking_for)};

  • the_id_that_you_are_looking_for будет длинным (может быть int, но по праву должно быть длинным), который передается / получается из того места, где вы вызываете запрос, например, в действии.

После того, как вопрос отредактирован.

Предполагая, что другие очереди для других дел работают, возможно, используйте: -

    case WORkOUT_EXERCISE:

        String table = WorkoutContract.WorkoutEntry.TABLE_NAME_EXERCISES +
            " INNER JOIN " + WorkoutContract.WorkoutEntry.TABLE_NAME_WORKOUT +
            " ON " + WorkoutContract.WorkoutEntry.TABLE_NAME_WORKOUT + "." +
            WorkoutContract.WorkoutEntry._ID + " = " +
            WorkoutContract.WorkoutEntry.TABLE_NAME_EXERCISES + "." +
            WorkoutContract.WorkoutEntry.WORKOUT_ID;


        String[] columns = new String[]{
            WorkoutContract.WorkoutEntry.EXERCISE_NAME,
            WorkoutContract.WorkoutEntry.WEIGHT,
            WorkoutContract.WorkoutEntry.REPS,
            WorkoutContract.WorkoutEntry.RPE               
        };

        String whereclause = WorkoutContract.WorkoutEntry._ID + " =?";

        cursor = db.query(table,columns,whereclause,selectionArgs,null,null,null);
        break;

Примечания

  • Это в основном использует метод запроса, как в других случаях, так как кажется, что основная проблема заключалась в том, что вы не знали, как включить JOIN (в основном это часть первого параметра).
    • первый пареметр, хотя в документации написано Имя таблицы, к которой нужно скомпилировать запрос. SQLiteDatabase - query на самом деле это предложение FROM и может быть довольно сложным (как указано выше).
  • Я не предполагал, что другие параметры могут быть использованы напрямую, поэтому вполне может быть, что проекция, где могут быть указаны выражение, оператор выбора и порядок сортировкииспользуется напрямую (, так что таблица может быть единственной переменной, на которой вам нужно сосредоточиться ).
  • Приведенный выше код является принципиальным кодом, он не былпротестировано или выполнено, поэтому может содержать ошибки.

В качестве альтернативы вы можете использовать: -

    case WORkOUT_EXERCISE:
        final String QUERY = "SELECT workouts._id, " +
                "exercise_name," +
                "weight," +
                "reps," +
                "rpe"+
                " FROM "+
                "exercises"+
                " INNER JOIN workouts ON workouts._id = exercises.workout_id"+
                " WHERE workouts._id=?";
       cursor = db.rawQuery(QUERY, selectionArgs);
        break;
  • Это предполагает, что selectionArgs является исключительноидентификатор передан.
  • Это было бы менее адаптируемо, чем предыдущий метод.
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...