具有多个表的MySQL IFNULL()仍然是';t工作


MySQL IFNULL() with multiple tables still isn't working

我知道我已经在这里问了这个问题,但没有一个好的答案,所以我再试一次,这次我希望我能为你们提供足够的信息。

在我提出问题之前,我将向您展示我是如何创建数据库的(有用的部分):

CREATE TABLE host(
        id INT NOT NULL AUTO_INCREMENT PRIMARY KEY,
        naam VARCHAR(40) NOT NULL,
        isActief BOOLEAN NOT NULL DEFAULT TRUE,
        UNIQUE unq_host_naam(naam)
);

CREATE TABLE shows(
        id INT NOT NULL AUTO_INCREMENT PRIMARY KEY,
        naam VARCHAR(30) NOT NULL,
        facebook VARCHAR(50) DEFAULT NULL,
        twitter VARCHAR(50) DEFAULT NULL,
        isNonStop BOOLEAN NOT NULL DEFAULT FALSE,
        showProgrammaInMenu BOOLEAN NOT NULL DEFAULT TRUE,
        isActief BOOLEAN NOT NULL DEFAULT TRUE,
        UNIQUE unq_shows_naam(naam)
);

/* The following tables (day and hour) were created because MySQL doesn't have CHECK-constraints*/
CREATE TABLE day( id INT NOT NULL PRIMARY KEY );
INSERT INTO day
        VALUES (1), (2), (3), (4), (5), (6), (7);
CREATE TABLE hour( id INT NOT NULL PRIMARY KEY );
INSERT INTO hour
        VALUES (0), (1), (2), (3), (4), (5), (6), (7), (8), (9), (10), (11), (12), (13), (14), (15), (16), (17), (18), (19), (20), (21), (22), (23);

CREATE TABLE schedule(
        id INT NOT NULL AUTO_INCREMENT PRIMARY KEY,
        dag INT NOT NULL,
        uur INT NOT NULL,
        showId INT,
        hostId INT,
        FOREIGN KEY fk_schedule_day(dag) REFERENCES day(id),
        FOREIGN KEY fk_schedule_hour(uur) REFERENCES hour(id),
        FOREIGN KEY fk_schedule_shows(showId) REFERENCES shows(id),
        FOREIGN KEY fk_schedule_host(hostId) REFERENCES host(id),
        UNIQUE unq_schedule_dag_uur(dag, uur)
);

我正在尝试运行此查询:

$query = sprintf("SELECT s.dag, s.uur, h.naam hostName
                FROM schedule s, host h
                WHERE dag IN (SELECT dag
                                FROM schedule
                                WHERE showId = %s)
                    AND s.hostId = h.id,
                    AND s.showId = %s
                ORDER BY dag, uur",
            mysqli_real_escape_string($con, $id),
            mysqli_real_escape_string($con, $id));

我知道它不起作用,因为hostId可能为NULL,所以我尝试使用MySQL的IFNULL()方法修复它:

SELECT s.dag, s.uur, IFNULL(h.naam, "") hostname

但这并没有奏效。此外,这里提到的选项也不起作用,因为它只是中和了自己。。。

$query = sprintf("SELECT s.dag, s.uur, h.naam hostName
                FROM schedule s, host h
                WHERE dag IN (SELECT dag
                                FROM schedule
                                WHERE showId = %s)
                    AND (s.hostId = h.id OR ISNULL(s.hostId))
                    AND s.showId = %s
                ORDER BY dag, uur",
            mysqli_real_escape_string($con, $id),
            mysqli_real_escape_string($con, $id));

这和我在没有的情况下使用它是一样的

AND (h.id = s.hostId OR ISNULL(s.hostId))

您的查询有点混乱。。你想干什么?

您的子查询从showId为传入变量的日程中选择日期,并将其与由相同showId筛选的另一个日程的日期进行比较。。这毫无意义。

为什么要订购子查询?

此外,正如我在评论中提到的,如果一天是NULL,如果LHS是NULL,或者如果RHS中没有匹配项,并且其中一个值是NULL,则IN将返回NULL(对于条件为false)。

您还使用了隐式联接,这使您更难判断发生了什么。看起来您想要一个LEFT JOIN,在没有主机的情况下返回时间表。

似乎您已经尝试过编写以下逻辑等价物:

   SELECT s.day, s.hour, COALESCE(h.name,'') hostName
     FROM schedule s
LEFT JOIN host h
       ON h.id = s.hostId
    WHERE s.showId = %s
 ORDER BY s.day, s.hour

此外,请详述"不起作用";错误?什么都不回?没有返回预期结果?如果不解释你想做什么…"不起作用"是没有用的。