【问题标题】:SQL query to join two tables despite the other table may not have values连接两个表的 SQL 查询,尽管另一个表可能没有值
【发布时间】:2013-12-05 15:30:44
【问题描述】:

我正在尝试查询两个 Wordpress 表,即。 postspostmeta

基本上我感兴趣的表和行是这样的:

| ---- ** posts ** ---- |    | -------- ** postmeta ** ---------- |
| ID       | post_type  |    | post_id  | meta_key   | meta_value |
|-----------------------|    |------------------------------------|
| 1        | player     |    | 1        | number     | 10         |
| 2        | player     |    | 2        | number     | 20         |
| 3        | player     |    | 3        | othre_key  | aaa        |
| 4        | other_type |    | 4        | other_key  | xxx        |
| 4        | other_type |    | 5        | other_key  | yyy        |
| 4        | other_type |    | 6        | other_key  | zzz        |

我想获取post_type = player 的所有帖子,并按postmeta.meta_value 对它们进行排序,其中postmeta.meta_key = number 是否存在postmeta 行。

到目前为止,我得到了这个:

SELECT a.ID, a.post_title, b.meta_value, b.meta_key
FROM $wpdb->posts AS a
INNER JOIN $wpdb->postmeta AS b
    ON a.ID = b.post_id
    AND b.meta_key = %s
WHERE a.post_status = %s
    AND a.post_type = %s
GROUP BY a.ID
ORDER BY b.meta_value+(0) ASC, a.post_title ASC

...返回具有与其关联的数字 postmeta 的玩家。

如何将没有该 postmeta 的玩家附加到同一查询中的结果中,以便所需的结果看起来像这样?

| --- ** result ** ---- |
| ID       | meta_value |
|-----------------------|
| 1        | 10         |
| 2        | 20         |
| 3        | null       |

【问题讨论】:

    标签: mysql wordpress


    【解决方案1】:

    使用LEFT JOIN 代替INNER JOIN

    SELECT a.ID, a.post_title, b.meta_value, b.meta_key
    FROM $wpdb->posts AS a
    LEFT JOIN $wpdb->postmeta AS b
        ON a.ID = b.post_id
        AND b.meta_key = %s
    WHERE a.post_status = %s
        AND a.post_type = %s
    GROUP BY a.ID
    ORDER BY b.meta_value+(0) ASC, a.post_title ASC
    

    正如您在this great explanation of JOINS 中看到的,只要匹配 JOIN 条件,LEFT JOIN 就会返回 LEFT 表中的所有结果并添加 RIGHT 表中的信息。

    至于INNER JOIN,只返回符合join条件的结果

    【讨论】:

    • 所以,基本上要让有数字的玩家按升序排列,而没有的玩家,我必须将 sql 顺序替换为 DESC,然后翻转结果数组......因为现在是 null值是第一位的
    • 您可以向ORDER BY CASE WHEN b.meta_value IS NULL 2 ELSE 1 END,b.meta_value+(0) ASC, a.post_title ASC 添加验证。这会将具有 b.meta_value 的那些排序在没有的那些之前
    【解决方案2】:

    正如 Filipe 所说,您想使用 LEFT JOIN。

    左连接在很大程度上与内连接相同。它根据 on 规范将所有匹配的记录放在一起。

    不同之处在于 LEFT 表(您在连接运算符之前编写的表)中的所有记录也将在查询结果中返回。

    右表字段中的所有值都将设置为 NULL。

    此外,要仅从左表中获取与右表不匹配的行,您可以添加一个 where b.post_id IS NULL。

    SELECT a.ID, a.post_title, b.meta_value, b.meta_key
    FROM $wpdb->posts AS a
    LEFT JOIN $wpdb->postmeta AS b
        ON a.ID = b.post_id
        AND b.meta_key = %s
    WHERE a.post_status = %s
        AND a.post_type = %s
    GROUP BY a.ID
    ORDER BY b.meta_value+(0) ASC, a.post_title ASC
    

    【讨论】:

      猜你喜欢
      • 2016-05-27
      • 2011-09-12
      • 2017-07-05
      • 1970-01-01
      • 2020-11-10
      • 2022-08-12
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多