首页 > 解决方案 > 带有子查询的 Sqlite 查询返回空

问题描述

在我的应用程序中,我正在使用 sqlite 的子查询,子查询返回 3 个值,没关系,但在主查询中,返回空,我需要帮助。

*变量的某些部分是葡萄牙语,因为我是巴西人。

public List<Table_Anuncio_Empregador> getAllUser_Empregador() {
    SQLiteDatabase db = this.getReadableDatabase();
    List<Table_Anuncio_Empregador> anuncios = new ArrayList<Table_Anuncio_Empregador>();

    SharedPreferences preferences = context.getSharedPreferences("user_preferences", MODE_PRIVATE);
    int user_id = preferences.getInt("user_id_conectado",0);

    String selectQuery = "SELECT "+KEY_ID+", "+KEY_IMAGEM_ANUNCIO+", "+KEY_TITULO+", "+KEY_DESCRICAO+", "+KEY_CIDADE
                        + " FROM " + TABLE_ANUNCIO_EMPREGADOR
                        + " WHERE "+ KEY_ID +" IN (SELECT "+KEY_ANUNCIO_EMPREGADOR_ID+" FROM "+ TABLE_ANUNCIO
                        +" WHERE "+ KEY_ANUNCIO_PERFIL+" = 'empregador' AND "+ KEY_USER_ID+" = "+user_id+")";
    Log.e(LOG, selectQuery);
    Cursor c = db.rawQuery(selectQuery, null);
    if (c.moveToFirst()) {
        do {
            Table_Anuncio_Empregador anuncio = new Table_Anuncio_Empregador();
            anuncio.setAnuncio_empregador_id(c.getInt(c.getColumnIndex(KEY_ID)));
            anuncio.setImagem_do_anuncio(c.getBlob(c.getColumnIndex(KEY_IMAGEM_ANUNCIO)));
            anuncio.setTitulo(c.getString(c.getColumnIndex(KEY_TITULO)));
            anuncio.setDescricao(c.getString(c.getColumnIndex(KEY_DESCRICAO)));
            anuncio.setCidade(c.getString(c.getColumnIndex(KEY_CIDADE)));

            anuncios.add(anuncio);
        } while (c.moveToNext());
    }

    return anuncios;
}

LOG 将查询显示为:-

E/Banco_Helper: SELECT ID, Imagem_anuncio, Titulo, Descricao, Cidade FROM Anuncio_empregador WHERE ID IN (SELECT Anuncio_empregado_info_ID FROM Anuncio WHERE Anuncio_perfil = 'empregador' AND User_ID = 2)

这些表是使用以下方法创建的:-

private static final String CREATE_TABLE_ANUNCIO =
        "CREATE TABLE IF NOT EXISTS " + TABLE_ANUNCIO + "(" + KEY_ID + " INTEGER PRIMARY KEY AUTOINCREMENT," +
                KEY_USER_ID + " INTEGER NOT NULL," +
                KEY_ANUNCIO_PERFIL + " TEXT NOT NULL," +
                KEY_ANUNCIO_EMPREGADOR_ID + " INTEGER," +
                KEY_ANUNCIO_PRESTADOR_ID + " INTEGER," +

                KEY_CREATED_AT + " DATETIME NOT NULL" + ")";

和 :-

private static final String CREATE_TABLE_ANUNCIO_EMPREGADOR =
        "CREATE TABLE IF NOT EXISTS " + TABLE_ANUNCIO_EMPREGADOR + "(" + KEY_ID + " INTEGER PRIMARY KEY," +
                KEY_TITULO + " TEXT NOT NULL," +
                KEY_DESCRICAO + " TEXT NOT NULL," +
                KEY_BAIRRO + " TEXT NOT NULL," +
                KEY_CIDADE + " TEXT NOT NULL," +
                KEY_ESTADO + " TEXT NOT NULL," +
                KEY_LOCAL_SERVICO + " TEXT NOT NULL," +
                KEY_EXIGENCIAS + " TEXT," +
                KEY_IMAGEM_ANUNCIO + " BLOB NOT NULL" + ")";

等于:-

CREATE TABLE IF NOT EXISTS Anuncio( 
    ID INTEGER PRIMARY KEY AUTOINCREMENT,
    USER_ID INTEGER NOT NULL,
    Anuncio_perfil TEXT NOT NULL,
    Anuncio_empregado_info_ID INTEGER,
    ANUNCIO_PRESTADOR_ID INTEGER,
    CREATED_AT DATETIME NOT NULL
);

和 :-

CREATE TABLE IF NOT EXISTS Anuncio_empregador (
    ID INTEGER PRIMARY KEY,
    Titulo TEXT NOT NULL,
    Descricao TEXT NOT NULL,
    Bairro TEXT NOT NULL,
    Cidade TEXT NOT NULL,
    Estado TEXT NOT NULL,
    Local_Servico TEXT NOT NULL,
    Exigencias TEXT,
    Imagem_anuncio BLOB NOT NULL
);

标签: javaandroidsqlite

解决方案


我相信您的问题在于实际数据而不是查询。

也就是说,以下内容用于创建和填充这两个表并运行查询(加上一些中间查询)。结果是包含了三个预期的行,而应该排除了三个行。那就是有问题的查询以预期的结果运行

使用了以下 SQL:-

DROP TABLE IF EXISTS Anuncio;
CREATE TABLE IF NOT EXISTS Anuncio( 
    ID INTEGER PRIMARY KEY AUTOINCREMENT,
    USER_ID INTEGER NOT NULL,
    Anuncio_perfil TEXT NOT NULL,
    Anuncio_empregado_info_ID INTEGER,
    ANUNCIO_PRESTADOR_ID INTEGER,
    CREATED_AT DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP
);


DROP TABLE IF EXISTS Anuncio_empregador;
CREATE TABLE IF NOT EXISTS Anuncio_empregador (
    ID INTEGER PRIMARY KEY,
    Titulo TEXT NOT NULL,
    Descricao TEXT NOT NULL,
    Bairro TEXT NOT NULL,
    Cidade TEXT NOT NULL,
    Estado TEXT NOT NULL,
    Local_Servico TEXT NOT NULL,
    Exigencias TEXT,
    Imagem_anuncio BLOB NOT NULL DEFAULT X'00010203040506070809'
)
;   

INSERT INTO Anuncio_empregador 
    (Titulo,Descricao,Bairro,Cidade,Estado,Local_Servico,Exigencias)
    VALUES
        ('Mr','Albert','Bloggs','something','something else','xxx','xxxx'),
        ('Mr','Bert','Bloggs','something','something else','xxx','xxxx'),
        ('Mr','Charlie','Bloggs','something','something else','xxx','xxxx'),
        ('Mr','Dave','Bloggs','something','something else','xxx','xxxx'),
        ('Mr','Eddie','Bloggs','something','something else','xxx','xxxx'),
        ('Mr','Fred','Bloggs','something','something else','xxx','xxxx'),
        ('Mr','George','Bloggs','something','something else','xxx','xxxx')
    ;
    
SELECT * FROM Anuncio_empregador;

INSERT INTO Anuncio
    (USER_ID, Anuncio_perfil,Anuncio_empregado_info_ID,ANUNCIO_PRESTADOR_ID)
    VALUES
        (1,'empregador',1,100),
        (2,'empregador',2,100),
        (3,'empregador',3,100),
        (4,'not an empregador',1,100),
        (5,'not an empregador',2,100),
        (6,'not an empregador',3,100)
    ;
    
SELECT * FROM Anuncio;

SELECT * FROM Anuncio WHERE Anuncio_perfil = 'empregador';
                            
SELECT ID,Imagem_anuncio,Titulo,Descricao,Cidade
FROM Anuncio_empregador
WHERE ID IN 
    (
        SELECT Anuncio_empregado_info_ID 
        FROM ANUNCIO 
        WHERE ANUNCIO_PERFIL = 'empregador' AND USER_ID = user_id
        )
;
  • 请注意,采取了一些自由,例如
    • 使用 CURRENT_TIMESTAMP 和
    • 使用 X'00010203040506070809'
  • 省去了重复这些对 SQL 的工作没有影响的值。

生成的Anuncio_empregador表为:-

在此处输入图像描述

生成的Anuncio表为:-

在此处输入图像描述

  • 即最后3行已根据子句设置为排除WHERE ANUNCIO_PERFIL = 'empregador'

Question中的查询结果

SELECT ID,Imagem_anuncio,Titulo,Descricao,Cidade
FROM Anuncio_empregador
WHERE ID IN 
    (
        SELECT Anuncio_empregado_info_ID 
        FROM ANUNCIO 
        WHERE ANUNCIO_PERFIL = 'empregador' AND USER_ID = user_id
        )
;

存在 :-

在此处输入图像描述

  • 注意更改AND USER_ID = user_idAND USER_ID = 2只显示 Bert 的 1 行,正如预期的那样。

推荐阅读