4个表的三个INNER JOIN,查询中的某些值可能为空,也可能不为空

时间:2014-05-17 01:27:17

标签: mysql

在我网站的其中一个页面上,我使用了4个表(登录,统计,民意调查和宣布)的内部联接,如下所示:

$login_user = mysqli_real_escape_string($cxn, $_SESSION['user']);

$sqlAll = mysqli_fetch_assoc(mysqli_query($cxn, 
    "SELECT login.picture, login.statement,
    stats.wealth,
    MAX(poll.polltime) AS pollunixtime,
    MAX(announce.announcetime) AS announceunixtime 
    FROM login 
    INNER JOIN stats ON login.user = stats.user 
    INNER JOIN poll ON login.user = poll.user 
    INNER JOIN announce ON login.user = announce.source 
    WHERE (login.user = '$login_user' AND announce.announcetype = 'feedback')"));

只要表格宣布中的至少一行,并且为该用户填充表格民意调查中的一行,此内部联接就可以正常工作,例如,此表单输入的值定义为:

<form id="myForm"><input type="hidden" name="wealth" value="<?= $sqlAll['wealth'] ?>"></form>//"View Page Source" shows this value is defined and shows up as value="number"

但是,我注意到当用户的任何一个表都没有行时,查询失败,因为查询中的某些值未定义。例如,如果没有任何表的行,则此表单输入的值未定义:

<form id="myForm"><input type="hidden" name="wealth" value="<?= $sqlAll['wealth'] ?>"></form>//"View Page Source" shows this value is undefined and shows up as value=""

我尝试以各种方式将CASE引入我的查询,例如:

$sqlAll = mysqli_fetch_assoc(mysqli_query($cxn, 
    "SELECT login.picture, login.statement,
     stats.wealth,
     MAX(poll.polltime) AS pollunixtime,
     MAX(announce.announcetime) AS announceunixtime
     FROM login
     INNER JOIN stats ON login.user = stats.user
     INNER JOIN poll ON CASE WHEN poll.polltime IS NOT NULL THEN login.user = poll.user END 
     INNER JOIN announce ON CASE WHEN announce.announcetime IS NOT NULL THEN login.user = announce.source END 
     WHERE (login.user = '$login_user' AND announce.announcetype = 'feedback')"));

由于polltime和announcetime属于INT类型,我也尝试使用&#34;&gt;&#34;如下:

$sqlAll = mysqli_fetch_assoc(mysqli_query($cxn, 
    "SELECT login.picture, login.statement,
    stats.wealth,
    MAX(poll.polltime) AS pollunixtime,
    MAX(announce.announcetime) AS announceunixtime 
    FROM login
    INNER JOIN stats ON login.user = stats.user 
    INNER JOIN poll ON CASE WHEN poll.polltime > 0 THEN login.user = poll.user END    
    INNER JOIN announce ON CASE WHEN announce.announcetime > 0 THEN login.user = announce.source END 
    WHERE (login.user = '$login_user' AND announce.announcetype = 'feedback')"));

我还尝试过使用民意调查宣布放置CASE声明的变体,如下所示:

$sqlAll = mysqli_fetch_assoc(mysqli_query($cxn, 
    "SELECT login.picture, login.statement, 
     stats.wealth, 
     CASE WHEN MAX(poll.polltime) IS NOT NULL THEN 'pollunixtime' END, 
     CASE WHEN MAX(announce.announcetime) IS NOT NULL THEN 'announceunixtime' END 
     FROM login 
     INNER JOIN stats ON login.user = stats.user 
     INNER JOIN poll ON login.user = poll.user 
     INNER JOIN announce ON login.user = announce.source 
     WHERE (login.user = '$login_user' AND announce.announcetype = 'feedback')"));

我尝试的变化没有奏效。基本上,我需要一个CONDITIONAL INNER JOIN,以便在给定用户存在polltime和announcetime时执行第二和第三内部联接,否则不执行第二和第三内部联接。这可能吗?

请注意我已经有一个黑客解决方案,在这个系统中涉及将上面的一个查询分解为3个单独的查询,并使用ISSET测试给定用户的polltime和announcetime是否存在。我想比这个解决方案做得更好!

1 个答案:

答案 0 :(得分:1)

使用LEFT JOIN代替INNER JOIN,您可以采取与您所要求的相似的方式。