复杂的选择说明

时间:2014-01-04 22:59:12

标签: mysql sql

作为this usefull answer确实设法解决我的问题的后续行动,我发回信息是因为,说实话,我并不完全理解这一点(对我来说很复杂)SELECT。

如果有人可以让我了解数据计算(为什么要将其分成a b c)和CROSS JOIN部分,我将不胜感激。

这个答案在我的代码中进行了极大的性能升级,所以我认为在这里为每个人解释这个方法是有用的。

干杯

SELECT dates.Date,
       coalesce(s.daily_price, 0) AS price, s.id_item AS house
FROM
  (SELECT a.Date
   FROM
     ( SELECT '$to' - INTERVAL (a.a + (10 * b.a) + (100 * c.a)) DAY AS Date, '0' AS price
      FROM
        (SELECT 0 AS a
         UNION ALL SELECT 1
         UNION ALL SELECT 2
         UNION ALL SELECT 3
         UNION ALL SELECT 4
         UNION ALL SELECT 5
         UNION ALL SELECT 6
         UNION ALL SELECT 7
         UNION ALL SELECT 8
         UNION ALL SELECT 9) AS a
      CROSS JOIN
        (SELECT 0 AS a
         UNION ALL SELECT 1
         UNION ALL SELECT 2
         UNION ALL SELECT 3
         UNION ALL SELECT 4
         UNION ALL SELECT 5
         UNION ALL SELECT 6
         UNION ALL SELECT 7
         UNION ALL SELECT 8
         UNION ALL SELECT 9) AS b
      CROSS JOIN
        (SELECT 0 AS a
         UNION ALL SELECT 1
         UNION ALL SELECT 2
         UNION ALL SELECT 3
         UNION ALL SELECT 4
         UNION ALL SELECT 5
         UNION ALL SELECT 6
         UNION ALL SELECT 7
         UNION ALL SELECT 8
         UNION ALL SELECT 9) AS c) a
   WHERE a.Date BETWEEN '$from' AND '$to'
   ORDER BY a.Date) dates
LEFT JOIN ".T_ITEM_SEASONS." s ON dates.Date BETWEEN s.season_start AND s.season_end

编辑:在我原来的问题中,我添加了一个在下面讨论的错误。有缺陷的代码是:
300 * c.a ( SELECT '$to' - INTERVAL (a.a + (10 * b.a) + (300 * c.a)) DAY AS Date,

1 个答案:

答案 0 :(得分:2)

3个交叉连接只生成笛卡尔积

{0, 1,2,..., 9} x {0, 1,2,..., 9} x {0, 1,2,..., 9}
a                 b                 c

这部分(我们将其命名为x)

( SELECT curdate() - INTERVAL (a.a + (10 * b.a) + (100 * c.a)) DAY AS Date

基本上选择当前日期并从N天减去N = 0,1,2,...,999
使用笛卡尔积中生成的a,b和c值。注意每个这样的 N(每个数字< = 3位数)可写为N = a + 10 * b + 100 * c a,b和c的特定值。

最后这个日期x显然加入了你的赛季表 将每个日期x放入正确的季节。其余的应该是 我想,对你来说比对我更清楚。

我认为对你做出回应的人本可以避免 这两个交叉连接,如果他写了类似的东西:

     (SELECT 0 AS a
     UNION ALL SELECT 1
     UNION ALL SELECT 2
     UNION ALL SELECT 3
     UNION ALL SELECT 4
     UNION ALL SELECT 5
     ..........
     UNION ALL SELECT 997
     UNION ALL SELECT 998
     UNION ALL SELECT 999) AS a

但他想让它更紧凑(并避免写1000行) 但如果他这样做了,那就简化了x本来就是

( SELECT curdate() - INTERVAL (a.a) DAY AS Date

这是我阅读作者查询的方式。

修改

这是一个小型Java程序,用于演示
你有缺口/错过你的方式 即使用a.a + (10 * b.a) + (300 * c.a)公式。

    import java.util.TreeMap;

    public class Test050 {

        public static void main(String[] args) {
            TreeMap<Integer, Boolean> v = new TreeMap<Integer, Boolean>();
            for (int a=0; a<10; a++){
                for (int b=0; b<10; b++){
                    for (int c=0; c<10; c++){
                        int r = a + 10 * b + 300 * c;
                        v.put(r, Boolean.TRUE);
                    }
                }
            }

            for (int key : v.keySet()){
                System.out.println(key);
            }
        }

    }