【问题标题】:Join table in MySQL with "WHERE field < NUM"在 MySQL 中使用“WHERE 字段 < NUM”连接表
【发布时间】:2014-02-13 15:32:44
【问题描述】:

我的数据库中有两个需要加入的表。第一个如果words,第二个votes。表words 包含英文单词,表votes 是用于单词翻译的投票。每个这样的投票都有字段“权重”。当普通用户投票时,新条目创建的权重 = 1,如果管理员 - 权重 = 10。

我需要选择所有没有管理员投票的单词(使用单个查询)。

这是我正在尝试执行的查询的简化版本

SELECT w.* FROM words AS w
LEFT JOIN votes AS v ON w.word = v.word
WHERE v.weight < 10 // help me out here

假设有投票的表有这样的条目。

[id]  [word]   [translation]   [weight]
1     you      ты              1
2     you      вы              10
3     you      ваши            1
4     hello    привет          1
5     hello    привет          1

所以“你”这个词不应该被选中,因为它有管理员的投票权。

【问题讨论】:

  • 你在找WHERE v.weight &lt; 10 AND word &lt;&gt;'you'吗?

标签: php mysql sql join


【解决方案1】:

您可以通过where 子句中的比较来做到这一点:

SELECT w.*
FROM words w
WHERE not exists (select 1 from votes v where v.word = w.word and v.weight = 10);

即选择所有不存在管理员投票记录的单词。

【讨论】:

    【解决方案2】:

    根据您的数据库设置以及 MySQL 如何决定在您的数据库环境中解释查询,有 3 种备选方案在可读性和性能方面大都不同。

    经典子查询:

    SELECT  w.*
    FROM    words w
    WHERE   NOT EXISTS(
                SELECT  1
                FROM    votes v
                WHERE   v.word = w.word
                AND     v.weight = 10
            )
    

    IN() 子查询:

    SELECT  w.*
    FROM    words w
    WHERE   w.word NOT IN(
                SELECT  v.word
                FROM    votes v
                WHERE   v.weight = 10
            )
    

    为空的左连接:

    SELECT    w.*
    FROM      words w
    LEFT JOIN votes v
    ON        (   v.word = w.word
              AND v.weight = 10
              )
    WHERE     v.weight IS NULL
    

    除非我打错字,否则所有这些都应该给出相同的结果,但具有不同的性能特征,所以我建议您全部尝试并检查哪个最适合您的情况。

    【讨论】:

    • 糟透了......我已经尝试了你建议的所有方法,但它们都太重了,查询需要超过 30 秒,所以我的 apache 返回超时错误。也许那是因为我的桌子太大了:(
    • 那么你很可能没有关于 votes.word 和 votes.weight 的索引。确保您的索引设置正确并使用“EXPLAIN SELECT ...”检查它是否正在使用这些索引。我们拥有包含数千万条条目的表,并且可以在不到一秒的时间内执行此类查询。
    【解决方案3】:
    SELECT * FROM votes
    WHERE max(weight)=1
    GROUP BY word
    

    【讨论】:

    • WHERE 发生在分组之前,因此 WHERE MAX(weight) 不起作用。您必须改用 HAVING。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-10-05
    • 2015-08-11
    • 2021-05-13
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多