MySQL UNION无法正常工作

时间:2017-07-06 15:43:39

标签: mysql

我尝试了一个mysql联盟,但没有返回任何内容?以下是一个例子。总共有16个选择查询

$url_array = array(
   "euro-gbp","euro-aud","euro-usd",
   "euro-jpy","gbp-jpy","euro-cad",
   "usd-cad","usd-jpy","cad-jpy",
   "gbp-usd","aud-usd","gbp-cad",
   "aud-cad","aud-jpy","aud-nzd",
   "euro-nzd","gbp-aud","gbp-nzd",
   "nzd-usd","nzd-cad","nzd-jpy");

foreach($url_array as $urls) {
   $sql[]= "SELECT * 
     FROM `data_analysis_child` 
     WHERE type='".$urls."' 
     ORDER BY id DESC 
     LIMIT 2";

}

$sql = implode(" UNION ",$sql);

sql结果

SELECT * FROM `data_analysis_child` WHERE type='euro-gbp' ORDER BY id DESC LIMIT 2 UNION SELECT * FROM `data_analysis_child` WHERE type='euro-aud' ORDER BY id DESC LIMIT 2 UNION SELECT * FROM `data_analysis_child` WHERE type='euro-usd' ORDER BY id DESC LIMIT 2 UNION SELECT * FROM `data_analysis_child` WHERE type='euro-jpy' ORDER BY id DESC LIMIT 2 UNION SELECT * FROM `data_analysis_child` WHERE type='gbp-jpy' ORDER BY id DESC LIMIT 2 UNION SELECT * FROM `data_analysis_child` WHERE type='euro-cad' ORDER BY id DESC LIMIT 2 UNION SELECT * FROM `data_analysis_child` WHERE type='usd-cad' ORDER BY id DESC LIMIT 2 UNION SELECT * FROM `data_analysis_child` WHERE type='usd-jpy' ORDER BY id DESC LIMIT 2 UNION SELECT * FROM `data_analysis_child` WHERE type='cad-jpy' ORDER BY id DESC LIMIT 2 UNION SELECT * FROM `data_analysis_child` WHERE type='gbp-usd' ORDER BY id DESC LIMIT 2 UNION SELECT * FROM `data_analysis_child` WHERE type='aud-usd' ORDER BY id DESC LIMIT 2 UNION SELECT * FROM `data_analysis_child` WHERE type='gbp-cad' ORDER BY id DESC LIMIT 2 UNION SELECT * FROM `data_analysis_child` WHERE type='aud-cad' ORDER BY id DESC LIMIT 2 UNION SELECT * FROM `data_analysis_child` WHERE type='aud-jpy' ORDER BY id DESC LIMIT 2 UNION SELECT * FROM `data_analysis_child` WHERE type='aud-nzd' ORDER BY id DESC LIMIT 2 UNION SELECT * FROM `data_analysis_child` WHERE type='euro-nzd' ORDER BY id DESC LIMIT 2 UNION SELECT * FROM `data_analysis_child` WHERE type='gbp-aud' ORDER BY id DESC LIMIT 2 UNION SELECT * FROM `data_analysis_child` WHERE type='gbp-nzd' ORDER BY id DESC LIMIT 2 UNION SELECT * FROM `data_analysis_child` WHERE type='nzd-usd' ORDER BY id DESC LIMIT 2 UNION SELECT * FROM `data_analysis_child` WHERE type='nzd-cad' ORDER BY id DESC LIMIT 2 UNION SELECT * FROM `data_analysis_child` WHERE type='nzd-jpy' ORDER BY id DESC LIMIT 2

我如何解决?有没有更好的方法来重构此查询?

4 个答案:

答案 0 :(得分:2)

如果你需要每个选择的顺序和限制,你应该在每个选择

周围使用()
  foreach($url_array as $urls) {
        $sql[]= " (  SELECT * FROM `data_analysis_child` WHERE type='".$urls."' ORDER BY id DESC LIMIT 2  )";
        break;
    }

答案 1 :(得分:1)

只需一点额外的操作即可。如果获得零结果,则使用UNION ALL而不是UNION。实际上,在UNION中避免了重复记录,但是使用UNION ALL,您将获得查询返回的所有信息。尝试一下!!!

答案 2 :(得分:0)

你可以这样做:

SELECT *
FROM (
  SELECT @rank := if (@last_type=type, @rank+1, 1) as type_rank, *
  FROM data_analysis_child
  WHERE type IN ('euro-gbp', 'euro-aud', 'euro-usd'....)
  ORDER BY id DESC
)
WHERE type_rank<=2;

但表现会很糟糕。

根据索引的配置方式并假设您的id列是唯一的,这可能会更好:

SELECT 'first', dac1.*
FROM data_analysis_child dac1
WHERE dac1.id IN (
   SELECT MAX(dac2.id)
   FROM data_analysis_child dac2
   WHERE dac2.type IN ('euro-gbp', 'euro-aud', 'euro-usd'....)
   GROUP BY dac2.type
)
UNION
SELECT 'second', dac3.*
FROM data_analysis_child dac3
WHERE dac3.id IN (
   SELECT MAX(dac4.id)
   FROM data_analysis_child dac4
   WHERE dac4.type IN ('euro-gbp', 'euro-aud', 'euro-usd'....)
   AND dac4.id NOT IN (
      SELECT MAX(dac5.id)
      FROM data_analysis_child dac5
      WHERE dac5.type IN ('euro-gbp', 'euro-aud', 'euro-usd'....)
      GROUP BY dac5.type
   ) 
   GROUP BY dac4.type
)

但它不能很好地扩展到每种类型的前N个值。

更好的解决方案是将第一个或第二个等级的状态标记为记录上的属性并直接过滤。

答案 3 :(得分:0)

UNION的文档清楚地解释了:

  

要将ORDER BYLIMIT应用于个人SELECT,请将该子句放在括起SELECT的括号内:

(SELECT a FROM t1 WHERE a=10 AND B=1 ORDER BY a LIMIT 10)
UNION
(SELECT a FROM t2 WHERE a=11 AND B=2 ORDER BY a LIMIT 10);

它还说:

  

注意

     

以前版本的MySQL可能会允许这样的语句没有括号。在MySQL 5.7中,强制要求括号。

如果您使用的是MySQL 5.7或更高版本,则代码不会返回任何内容,因为查询未运行。您应该检查返回值的类型(查询函数在查询无效时返回FALSE)和错误消息。