LEFT JOIN有例外

时间:2015-10-08 21:56:13

标签: mysql join case

这是我当前的查询:

$q = "SELECT u.uid,CONCAT_WS(' ', u.first_name, u.last_name) name, CASE WHEN t.name IS NULL THEN 0 ELSE t.name END AS teamname ";
$q .= "FROM {$users} ";
$q .= "LEFT JOIN {$schedule} ON u.uid = s.uid ";
$q .= "LEFT JOIN {$products} ON p.admitting_id = u.uid ";
$q .= "LEFT JOIN {$teams} ON t.id = s.team ";
$q .= "WHERE (u.uid = {$current_user_id} AND u.roles = 'hoa') OR ";
$q .= "(p.id={$pid} AND p.admitting_id != 0) OR ";
$q .= "(t.admitting = 1 AND s.inactive != 1 AND s.role = 'hoa' AND (s.date = '{$today}' OR (s.date = '{$yesterday}' AND t.overnight = 1))) ";
$q .= "ORDER BY u.last_name,u.first_name,t.name";

我需要得到的是:

  1. 当前用户,如果当前用户有角色hoa
  2. uid与产品表中的admitting_id匹配的用户
  3. 所有具有角色的用户如今安排或昨天安排在夜班。对于那些预定用户,我需要他们所安排的团队的名称。重复的uid是好的,因为如果他们被安排在多个团队中,我需要所有不同的团队名称。
  4. 我不需要得到的是:

    • 上面选项1和2的团队名称。

    我得到的是:

    1. 上面#3的一切都很完美。
    2. 上面#1和#2的所有可能的团队名称,而我希望团队名称如果不在时间表上则为0。
    3. 我可以把它分成三个查询,但这不是更好。

1 个答案:

答案 0 :(得分:1)

有时格式化查询有助于可视化。我同意,它不需要成为三个查询。

你能提供一些示例模式和数据吗,理想情况是在问题描述和sqlfiddle之类的东西上供我们玩吗?

很难看到您的结构和数据,但我推测问题是users表格中的每条记录都加入schedule on您使用过的条款。

您可以将条件3的逻辑移到on子句中(它是left join,因此没有其他任何内容会中断)或者在CASE语句中将其复制SELECT

$q = <<<SQL
SELECT
    u.uid,
    CONCAT_WS(' ', u.first_name, u.last_name) name,
    IF(
        WHEN t.name IS NULL THEN
            0
        ELSE
            t.name
    END AS teamname 
FROM {$users} AS u
LEFT JOIN {$schedule} AS s ON (u.uid = s.uid)
LEFT JOIN {$products} AS p ON (p.admitting_id = u.uid)
LEFT JOIN {$teams} AS t ON
(
    t.id = s.team AND
    t.admitting = 1 AND
    s.inactive != 1 AND
    s.role = 'hoa' AND
    (
       s.date = '{$today}'
       OR
       (
           s.date = '{$yesterday}' AND
           t.overnight = 1
       )
    )
)
WHERE
    (  -- 1: Current User, if Current User has role hoa
        u.uid = {$current_user_id} AND
        u.roles = 'hoa'
    )
    OR
    (  -- 2: User where uid matches admitting_id from products table
        p.id={$pid} AND
        p.admitting_id != 0
    )
    OR 
    t.name IS NOT NULL
ORDER BY
    u.last_name,
    u.first_name,
    t.name
SQL;

我绝对不确定如果没有真正的东西可以解决你的问题......很高兴继续寻找你是否可以提供一个有效的沙坑实例。