mysql:在匹配查询中使用动态字段

时间:2017-12-21 18:00:15

标签: mysql full-text-search

遇到此查询的问题:

        SELECT contests.*, 
   ( 
          SELECT Count(*) 
          FROM   participants 
          WHERE  participants.contest_id = contests.id 
          AND    participants.active = 1 
          AND    participants.deleted = 0) AS cur_participants, 
   ( 
          SELECT path 
          FROM   media 
          WHERE  media.entity_type = 'contests' 
          AND    media.entity_id = contests.id 
          AND    deleted = 0 
          AND    type = 'img' 
          AND    is_primary = 1) AS thumbnail, 
   ( 
          SELECT description 
          FROM   ( 
                        SELECT contest_id, 
                               description, 
                               deleted 
                        FROM   rewards_assets 
                        UNION 
                        SELECT contest_id, 
                               description, 
                               deleted 
                        FROM   rewards_cars 
                        UNION 
                        SELECT contest_id, 
                               description, 
                               deleted 
                        FROM   rewards_houses) AS rewards 
          WHERE  rewards.contest_id = contests.id 
          AND    rewards.deleted = 0) AS **reward**
          , (match (name) AGAINST ('car') + match (description) AGAINST ('car') + match (**reward**) AGAINST ('car')) AS rel 
    FROM   contests 
        WHERE active = 1 AND deleted = 0 AND end_date > UNIX_TIMESTAMP()
        HAVING rel > 0
        ORDER BY rel DESC
        LIMIT 0, 201

返回:

#1054 - Unknown column 'reward' in 'field list'
enter code here

似乎匹配函数无法使用" AS"创建的奖励字段。我尝试将匹配部分直接移动到where子句和order by子句而不使用naimg {在SELECT中{1}},没有运气..

如何绕过它?

提前致谢

2 个答案:

答案 0 :(得分:1)

这里有两件事:

  1. 您无法在选择列表中的另一个表达式中引用别名。

    SELECT 123 AS x, x+1 AS y -- WRONG
    
    SELECT 123 AS x ... WHERE x = 123 -- WRONG
    

    解决方法是将别名定义放在派生表中。

    SELECT x, x+1 AS y FROM (SELECT 123 AS x) AS t
    
  2. MATCH()仅适用于已定义FULLTEXT索引的实列。您不能在MATCH()中引用任何类型的别名或派生列。所以上面的解决方法无论如何都不会起作用。

    CREATE TABLE MyTable ( t TEXT, FULLTEXT INDEX(t));
    
    SELECT MATCH(t2) AGAINST ('...') FROM (SELECT t AS t2 FROM MyTable) AS d;
    ERROR 1191 (HY000): Can't find FULLTEXT index matching the column list
    

答案 1 :(得分:0)

谢谢比尔, 您的回答非常有用,并帮助我找到解决此问题的方法:

        SELECT contests.*, 
   ( 
          SELECT Count(*) 
          FROM   participants 
          WHERE  participants.contest_id = contests.id 
          AND    participants.active = 1 
          AND    participants.deleted = 0) AS cur_participants, 
   ( 
          SELECT path 
          FROM   media 
          WHERE  media.entity_type = 'contests' 
          AND    media.entity_id = contests.id 
          AND    deleted = 0 
          AND    type = 'img' 
          AND    is_primary = 1) AS thumbnail 
          , (match (name) AGAINST ('car') + match (description) AGAINST ('car')) AS contest_rel, ( 
          SELECT reward_rel
          FROM   ( 
                        SELECT contest_id, 
                               match(description) AGAINST('car') AS reward_rel, 
                               deleted 
                        FROM   rewards_assets 
                        UNION 
                        SELECT contest_id, 
                               match(description) AGAINST('car') AS reward_rel, 
                               deleted 
                        FROM   rewards_cars 
                        UNION 
                        SELECT contest_id, 
                               match(description) AGAINST('car') AS reward_rel, 
                               deleted 
                        FROM   rewards_houses) AS rewards 
          WHERE  rewards.contest_id = contests.id 
          AND    rewards.deleted = 0) AS reward_rel 
    FROM   contests 
        WHERE active = 1 AND deleted = 0 AND end_date > UNIX_TIMESTAMP()
        HAVING (contest_rel+reward_rel) > 0
        ORDER BY (contest_rel+reward_rel) DESC
        LIMIT 0, 20

我直接在子查询中选择了奖励rel(该字段是全文索引的),然后在计算出所有匹配索引分开后,在外面(在拥有和排序中)进行数学运算。

非常感谢!