【问题标题】:SQLite INNER JOIN WHERE column not nullSQLite INNER JOIN WHERE 列不为空
【发布时间】:2015-08-15 22:42:44
【问题描述】:

我试图让这个 SQL 查询正确,但我一直得到一个空值的单行。

所以我有两张桌子。

表 A 是 chat 表。

表 B 是 wallpaper 表。

chat 可能会或可能不会将任何壁纸 ID 分配给外键。

我正在尝试使用以下查询将壁纸附加到聊天中:

const char *query = "SELECT wallpaper.* FROM wallpaper INNER JOIN chat ON wallpaper.id_wallpaper = chat.id_wallpaper AND (chat.id_chat = ? AND chat.id_wallpaper NOT NULL)";

在我的方法中:

-(Wallpaper *)getWallpaperForChatHeaderID:(NSString *)chatHeaderID
{
    sqlite3_stmt *statement;

    const char *query = "SELECT wallpaper.* FROM wallpaper INNER JOIN chat ON wallpaper.id_wallpaper = chat.id_wallpaper AND (chat.id_chat = ? AND chat.id_wallpaper NOT NULL)";

    Wallpaper *wallpaper = nil;

    if(sqlite3_prepare_v2(_database, query, -1, &statement, nil) == SQLITE_OK)
    {
        sqlite3_bind_int(statement, 1, [chatHeaderID intValue]);

        int statusCode = sqlite3_step(statement);

        if(statusCode == SQLITE_DONE)
        {
            long idWallpaper = sqlite3_column_int(statement, 0);

            char *dbFilename = (char *)sqlite3_column_text(statement, 1);

            ...

            wallpaper = [[Wallpaper alloc] initWithWallpaperID:idWallpaper ....];
        }
        else
        {
            NSLog(@"sql step status error code: %d", statusCode);
        }

        sqlite3_finalize(statement);
    }
    else
    {
        NSLog(@"Failed to get wallpaper for chat header with ID: %@", chatHeaderID);
    }

    return wallpaper;
}

但这一直给我返回一个所有字段为 NULL 的 wallpaper 实体。

一个聊天只能有 1 张壁纸。所以我只想获取一个wallpaper,它链接到由chatHeaderID 标识的基于聊天的聊天。

据我所知,SQL 查询根据我传入的chatHeaderIDchat 表中找到了匹配的chat 条目,但它似乎忽略了我的WHERE 子句:

(chat.id_chat = ? AND chat.id_wallpaper NOT NULL)

我期待看到的是 SQL 查询目前返回 0 个条目,因为我没有将任何壁纸条目与任何聊天条目相关联。

有什么想法吗? :D

【问题讨论】:

  • 实际上您缺少 WHERE 子句:const char *query = "SELECT wallpaper.* FROM wallpaper INNER JOIN chat ON wallpaper.id_wallpaper = chat.id_wallpaper WHERE chat.id_chat = ? AND chat.id_wallpaper NOT NULL";
  • 我当你把圆括号放在 (chat.id_chat = ? AND chat.id_wallpaper NOT NULL) 时,它意味着 WHERE ?抱歉,我的 SQL 知识还不是很远。
  • 我都测试过,似乎工作:P
  • 你为什么使用 inner 连接?
  • 我读到了一些关于 LEFT OUTER JOIN 不会消除 NULL 行或有匹配时的东西 (techonthenet.com/sqlite/joins.php),我不希望 SQL 返回包含 NULL 数据的行在我上面的代码中很明显,所以我使用了 INNER JOIN 并希望它可以解决我的过滤器问题,. LEFT OUTER JOIN 是否比 LEFT INNER JOIN 性能更好?

标签: ios sqlite inner-join


【解决方案1】:

我自己解决的另一个问题=/

不知道为什么上面的问题代码不起作用,但我找到了一个似乎可以产生预期结果的解决方法。

-(Wallpaper *)getWallpaperForChatHeaderID:(NSString *)chatHeaderID
{
    sqlite3_stmt *statement;

    const char *query = "SELECT wallpaper.* FROM wallpaper INNER JOIN chat ON wallpaper.id_wallpaper = chat.id_wallpaper WHERE chat.id_chat = ? AND chat.id_wallpaper NOT NULL";

    Wallpaper *wallpaper = nil;

    if(sqlite3_prepare_v2(_database, query, -1, &statement, nil) == SQLITE_OK)
    {
        sqlite3_bind_int(statement, 1, [chatHeaderID intValue]);

        while (sqlite3_step(statement) == SQLITE_ROW)
        {
            long idWallpaper = sqlite3_column_int(statement, 0);

            ...

            wallpaper = [[Wallpaper alloc] initWithWallpaperID:idWallpaper ...];
        }

        sqlite3_finalize(statement);
    }
    else
    {
        NSLog(@"Failed to get wallpaper for chat header with ID: %@", chatHeaderID);
    }

    return wallpaper;
}

这里的区别是我正在使用:

while(... == SQLITE_ROW) 
{ 
    ... 
}

条件来检查也满足 WHERE 过滤条件的匹配行:)

我想指出,我已将上述 SQL 查询更改为使用:

SELECT wallpaper.* FROM wallpaper INNER JOIN chat ON wallpaper.id_wallpaper = chat.id_wallpaper WHERE chat.id_chat = ? AND chat.id_wallpaper NOT NULL

但我已经测试过了:

SELECT wallpaper.* FROM wallpaper INNER JOIN chat ON wallpaper.id_wallpaper = chat.id_wallpaper AND (chat.id_chat = ? AND chat.id_wallpaper NOT NULL)

两者似乎都有效。

我将使用包含显式 WHERE 关键字的那个,因为它看起来更易读。

【讨论】:

    猜你喜欢
    • 2021-06-18
    • 2020-09-19
    • 2010-10-08
    • 1970-01-01
    • 1970-01-01
    • 2018-05-24
    • 2015-03-10
    • 1970-01-01
    • 2016-04-28
    相关资源
    最近更新 更多