Android 애플리케이션에서 두 개의 SQLite 테이블을 어떻게 조인합니까?

배경

나는 두 개의 테이블이있는 데이터베이스가 안드로이드 프로젝트를 가지고 tbl_questiontbl_alternative.

보기를 질문과 대안으로 채우기 위해 커서를 사용하고 있습니다. 두 테이블을 조인 할 때까지 필요한 데이터를 가져 오는 데 문제가 없습니다.

    Tbl_question
    -------------
    _신분증
    질문
    categoryid
    Tbl_alternative
    ---------------
    _신분증
    질문
    categoryid
    대안

다음과 같은 것을 원합니다.

SELECT tbl_question.question, tbl_alternative.alternative where 
categoryid=tbl_alternative.categoryid AND tbl_question._id = 
tbl_alternative.questionid.` 

이것은 내 시도입니다.

public Cursor getAlternative(long categoryid) {
            String[] columns = new String[] { KEY_Q_ID, KEY_IMAGE, KEY_QUESTION, KEY_ALT, KEY_QID};
             String whereClause = KEY_CATEGORYID + "=" + categoryid +" AND "+ KEY_Q_ID +"="+ KEY_QID;
             Cursor cursor = mDb.query(true, DBTABLE_QUESTION + " INNER JOIN "+ DBTABLE_ALTERNATIVE, columns, whereClause, null, null, null, null, null);
             if (cursor != null) {
                  cursor.moveToFirst();
             }
             return cursor;

이 방법을 사용하면 일반 SQL보다 쿼리를 더 어렵게 만들 수 있지만 오류가 적기 때문에이 방법을 사용하라는 조언을 받았습니다.

질문

내 애플리케이션에서 두 개의 SQLite 테이블을 어떻게 조인합니까?



답변

rawQuery 메소드 가 필요합니다 .

예:

private final String MY_QUERY = "SELECT * FROM table_a a INNER JOIN table_b b ON a.id=b.other_id WHERE b.property_id=?";

db.rawQuery(MY_QUERY, new String[]{String.valueOf(propertyId)});

사용하다 ? 원시 SQL 쿼리에 값을 넣는 대신 바인딩.


답변

또 다른 방법은 테이블처럼 쿼리되는 뷰를 구성하는 것입니다. 많은 데이터베이스 관리자에서보기를 사용하면 성능이 향상 될 수 있습니다.

CREATE VIEW xyz SELECT q.question, a.alternative
   FROM tbl_question AS q, tbl_alternative AS a
  WHERE q.categoryid = a.categoryid
    AND q._id = a.questionid;

이것은 메모리에서 가져온 것이므로 구문 문제가있을 수 있습니다.
http://www.sqlite.org/lang_createview.html

이 접근 방식을 언급 한 이유는 선호한다는 것을 암시 한대로 뷰와 함께 SQLiteQueryBuilder를 사용할 수 있기 때문입니다.


답변

확실히 올바른 @pawelzieba의 답변 외에도 두 테이블을 조인하는 동안 다음 INNER JOIN과 같이 사용할 수 있습니다.

SELECT * FROM expense INNER JOIN refuel
ON exp_id = expense_id
WHERE refuel_id = 1

이와 같은 원시 쿼리를 통해-

String rawQuery = "SELECT * FROM " + RefuelTable.TABLE_NAME + " INNER JOIN " + ExpenseTable.TABLE_NAME
        + " ON " + RefuelTable.EXP_ID + " = " + ExpenseTable.ID
        + " WHERE " + RefuelTable.ID + " = " +  id;
Cursor c = db.rawQuery(
        rawQuery,
        null
);

SQLite의 원시 쿼리 방법에 대한 이전 버전과의 호환성 지원으로 인해 해당 명령을 다음과 같이 변환합니다.

SELECT *
FROM expense, refuel
WHERE exp_id = expense_id AND refuel_id = 1

따라서 SQLiteDatabase.query () 도우미 메서드를 활용할 수 있습니다.

Cursor c = db.query(
        RefuelTable.TABLE_NAME + " , " + ExpenseTable.TABLE_NAME,
        Utils.concat(RefuelTable.PROJECTION, ExpenseTable.PROJECTION),
        RefuelTable.EXP_ID + " = " + ExpenseTable.ID + " AND " + RefuelTable.ID + " = " +  id,
        null,
        null,
        null,
        null
);

자세한 블로그 게시물은 http://blog.championswimmer.in/2015/12/doing-a-table-join-in-android-without-using-rawquery를 확인하세요.


답변

“모호한 열”은 일반적으로 동일한 열 이름이 두 개 이상의 테이블에 표시됨을 의미합니다. 데이터베이스 엔진은 원하는 것을 알 수 없습니다. 모호성을 제거하려면 전체 테이블 이름 또는 테이블 별칭을 사용하십시오.

여기 제 에디터에서 우연히 발견 한 예가 있습니다. 다른 사람의 문제에서 온 것이지만 어쨌든 이해가되어야합니다.

select P.*
from product_has_image P
inner join highest_priority_images H
        on (H.id_product = P.id_product and H.priority = p.priority)