Mysql变量里面有一个长查询

时间:2014-03-21 10:50:02

标签: mysql sql

我认为mysql 5.6上的mysql查询中存在变量问题:

SELECT DISTINCT TRIM(TRAILING '.' FROM merge_s.rdata) AS `content`,
            '120' AS ttl,
            `merge_s`.`pri` AS `prio`,
            (SELECT type FROM types WHERE type = @type:='MX') AS `type`,
            (SELECT id FROM soa WHERE CONCAT(SUBSTRING_INDEX((SELECT @rr:='mina.net'),'.',-2),'.')=soa.origin) AS domain_id,
            `merge_s`.`rr` AS `rr`
    FROM (`merge_s` LEFT JOIN `merge_s` `db2` ON
            (((`merge_s`.`rr` = `db2`.`rr`) AND (`merge_s`.`pri` < `db2`.`pri`) and (`merge_s`.`type` = `db2`.`type`))))
    WHERE ((`merge_s`.`status` = '1') OR (`merge_s`.`type` = 'NS') OR (`merge_s`.`type` = 'SOA')) AND
            (isnull(`db2`.`pri`) OR (`merge_s`.`type` = 'MX')) AND
            (merge_s.type=@type AND merge_s.rr=@rr)

查询返回正确但没有行。相同的查询,我用手替换最后一行(merge_s.type=@type AND merge_s.rr=@rr)与此变量中的i方面返回正确的2行

SELECT DISTINCT TRIM(TRAILING '.' FROM merge_s.rdata) AS `content`,
            '120' AS ttl,
            `merge_s`.`pri` AS `prio`,
            (SELECT type FROM types WHERE type = @type:='MX') AS `type`,
            (SELECT id FROM soa WHERE CONCAT(SUBSTRING_INDEX((SELECT @rr:='mina.net'),'.',-2),'.')=soa.origin) AS domain_id,
            `merge_s`.`rr` AS `rr`
    FROM (`merge_s` LEFT JOIN `merge_s` `db2` ON
            (((`merge_s`.`rr` = `db2`.`rr`) AND (`merge_s`.`pri` < `db2`.`pri`) and (`merge_s`.`type` = `db2`.`type`))))
    WHERE ((`merge_s`.`status` = '1') OR (`merge_s`.`type` = 'NS') OR (`merge_s`.`type` = 'SOA')) AND
            (isnull(`db2`.`pri`) OR (`merge_s`.`type` = 'MX')) AND
            (merge_s.type='MX' AND merge_s.rr='mina.net')

2行:

content         ttl     prio    type    domain_id   rr  
mail.mina.net   120     50       MX       3         mina.net
mail.tes.net    120     60       MX       3         mina.net

2 个答案:

答案 0 :(得分:0)

您可以将其置于SELECT

之上
SET @rr:='mina.net';

SELECT DISTINCT TRIM(TRAILING '.' FROM merge_s.rdata) AS `content`,
                '120' AS ttl,
                `merge_s`.`pri` AS `prio`,
                (SELECT type FROM types WHERE type = @type:='MX') AS `type`,
                (SELECT id FROM soa WHERE CONCAT(SUBSTRING_INDEX((SELECT @rr:='mina.net'),'.',-2),'.')=soa.origin) AS domain_id,
                `merge_s`.`rr` AS `rr`
        FROM (`merge_s` LEFT JOIN `merge_s` `db2` ON
                (((`merge_s`.`rr` = `db2`.`rr`) AND (`merge_s`.`pri` < `db2`.`pri`) and (`merge_s`.`type` = `db2`.`type`))))
        WHERE ((`merge_s`.`status` = '1') OR (`merge_s`.`type` = 'NS') OR (`merge_s`.`type` = 'SOA')) AND
                (isnull(`db2`.`pri`) OR (`merge_s`.`type` = 'MX')) AND
                (merge_s.type=@type AND merge_s.rr=@rr)

答案 1 :(得分:0)

在查询中,变量在select子句的子查询中设置:

SELECT DISTINCT TRIM(TRAILING '.' FROM merge_s.rdata) AS `content`,
       '120' AS ttl, `merge_s`.`pri` AS `prio`,
        (SELECT type FROM types WHERE type = @type:='MX') AS `type`,
        (SELECT id
         FROM soa
         WHERE CONCAT(SUBSTRING_INDEX((SELECT @rr:='mina.net'),'.',-2),'.')=soa.origin
        ) AS domain_id,
        `merge_s`.`rr` AS `rr`
FROM `merge_s` LEFT JOIN
     `merge_s` `db2`
      ON(((`merge_s`.`rr` = `db2`.`rr`) AND (`merge_s`.`pri` < `db2`.`pri`) and (`merge_s`.`type` = `db2`.`type`))))
WHERE ((`merge_s`.`status` = '1') OR (`merge_s`.`type` = 'NS') OR (`merge_s`.`type` = 'SOA')) AND
      (isnull(`db2`.`pri`) OR (`merge_s`.`type` = 'MX')) AND
      (merge_s.type=@type AND merge_s.rr=@rr);

你发现的是,在执行这样的子句之前,SQL语句中发生了很多处理。通常,from子句是执行的第一个子句,select是最后一个子句之一。我总是使用from将变量声明放在主cross join子句中。这个版本应该有效:

SELECT DISTINCT TRIM(TRAILING '.' FROM merge_s.rdata) AS `content`,
       '120' AS ttl, `merge_s`.`pri` AS `prio`,
        (SELECT type FROM types WHERE type = @type) AS `type`,
        (SELECT id
         FROM soa
         WHERE CONCAT(SUBSTRING_INDEX( @rr,'.',-2),'.')=soa.origin
        ) AS domain_id,
        `merge_s`.`rr` AS `rr`
FROM `merge_s` LEFT JOIN
     `merge_s` `db2`
      ON(((`merge_s`.`rr` = `db2`.`rr`) AND (`merge_s`.`pri` < `db2`.`pri`) and
          (`merge_s`.`type` = `db2`.`type`)))) cross join
      (select @type:='MX', @rr:='mina.net') const
WHERE ((`merge_s`.`status` = '1') OR (`merge_s`.`type` = 'NS') OR (`merge_s`.`type` = 'SOA')) AND
      (isnull(`db2`.`pri`) OR (`merge_s`.`type` = 'MX')) AND
      (merge_s.type=@type AND merge_s.rr=@rr);