2011-02-17 120 views
0

我想根据主表中的记录做一些计算,并希望将存储操作结果存储到单独的测试表中。MySQL中的嵌套查询帮助

>Table:Master: 
>C1   C2   C3  C4 
>---------- -------- --  -- 
>2011-02-19 Test-A  31  3 
>2011-02-19 Test-B  34  3 
>2011-02-19 Test-C  17  1 
>2011-02-15 Test-A* 48 =I 4 
>2011-02-15 Test-B  64  6 
>2011-02-15 Test-C  55  5 
>2011-02-11 Test-A  64 =I2 6 
>2011-02-11 Test-B  53  5 
>2011-02-11 Test-C  17  1 
>2011-02-10 Test-A  12 =I3 1 =J 
>2011-02-10 Test-B  02  0 
>2011-02-10 Test-C  54  5 

在同一天以随机方式进行的三种测试;但对于这种情况来说日期并不重要;只有最后三个测试记录用于计算。 我试图执行如下的顺序计算;使用第3个最早的元素例如,对于测试A,I(迭代)将是48(第3个最早的记录= c3列),因此R2将根据I2计算得出。而在R,R2,R3最后显示平均 - J.(C4 =最新记录。)

预期结果:

>Table:Test-A 
>SR Date  I  I2   I3   I4 
>-- ---------- ----- ----------- ----------- -------------------   
>1 2011/02/17 48  -52.96  -24.18  -10.71 

>Formula: 
>SR Date  R  R2   R3   R4 
>-- ---------- ----- ----------- ----------- -------------------   
>1 today()  48=C3 (I*0.23-I2) (I*0.23-I3) =avg(I,I1,I2,I3)-C4 

我想我需要使用与加入分/嵌套查询,但我无法弄清楚如何处理我;所有结果将被放置在单个测试表中。您的意见将非常感谢。 TIA

+2

太难以遵循,太难以阅读和理解数据。 – 2011-02-17 12:49:22

回答

1

设置测试用例:

CREATE TABLE `m1` 
(c1 DATE 
,c2 VARCHAR(6) 
,c3 SMALLINT 
,c4 TINYINT 
) DEFAULT CHARSET=latin1; 

INSERT INTO `m1` VALUES 
('2011-02-19','Test-A',31,3) 
,('2011-02-19','Test-B',34,3) 
,('2011-02-19','Test-C',17,1) 
,('2011-02-15','Test-A',48,4) 
,('2011-02-15','Test-B',64,6) 
,('2011-02-15','Test-C',55,5) 
,('2011-02-11','Test-A',64,6) 
,('2011-02-11','Test-B',53,5) 
,('2011-02-11','Test-C',17,1) 
,('2011-02-10','Test-A',12,1) 
,('2011-02-10','Test-B',02,0) 
,('2011-02-10','Test-C',54,5); 

这个查询利用一个局部变量(@i)的。在查询中提供test_name('Test-A')和日期('2011-02-17'),在这里显示为文字。

SELECT o.tn AS `Test` 
    , o.dt AS `Date` 
    , SUM(CASE WHEN o.n = 1 THEN o.c3*1.00 ELSE NULL END) AS R 
    , SUM(CASE WHEN o.n = 1 THEN o.c3*0.23 WHEN o.n = 2 THEN -1.00*o.c3 ELSE NULL END) AS R2 
    , SUM(CASE WHEN o.n = 1 THEN o.c3*0.23 WHEN o.n = 3 THEN -1.00*o.c3 ELSE NULL END) AS R3 
    , AVG(CASE WHEN o.n < 4 THEN c3*1.00 ELSE NULL END)-SUM(CASE WHEN n = 3 THEN c4*1.00 ELSE NULL END) AS R4 
    FROM (
     SELECT @i := @i + 1 AS n 
       , s.tn 
       , s.dt 
      -- , m.c1 
       , m.c3 
       , m.c4 
      FROM (SELECT '2011-02-17' AS dt,_latin1'Test-A' AS tn, @i := 0) s 
      JOIN m1 m 
      ON m.c2 = s.tn AND m.c1 <= s.dt 
      ORDER BY m.c1 DESC 
      LIMIT 0,3 
     ) o 
GROUP BY o.tn, o.dt 
HAVING SUM(1) >= 3 

您可以只运行内部查询,取消对m.c1选择列表,检查返回的行(第一,第二和第三最新的,提供的日期之前。

这个查询返回R3的值与问题中显示的值不同,但查询返回的结果似乎是给定公式的正确结果

此外,R4的公式参考5个值:avg(I,I1, I2,I3)-J3。查询中使用的公式有效= avg(I1,I2,I3)-J3

要得到的结果对于所有测试,作为一个给定的日期:

SELECT o.tn AS `Test` 
    , o.dt AS `Date` 
    , SUM(CASE WHEN o.n = 1 THEN o.c3 ELSE NULL END) AS R 
    , SUM(CASE WHEN o.n = 1 THEN o.c3*0.23 WHEN o.n = 2 THEN -1.00*o.c3 ELSE NULL END) AS R2 
    , SUM(CASE WHEN o.n = 1 THEN o.c3*0.23 WHEN o.n = 3 THEN -1.00*o.c3 ELSE NULL END) AS R3 
    , AVG(CASE WHEN o.n <= 3 THEN c3*1.00 ELSE NULL END)-SUM(CASE WHEN n = 3 THEN c4 ELSE NULL END) AS R4 
    FROM (
     SELECT @i := CASE WHEN @prev_tn = m.c2 THEN @i + 1 ELSE 1 END AS n 
       , @prev_dt := s.dt AS dt 
       , @prev_tn := m.c2 AS tn 
       , m.c1 
       , m.c3 
       , m.c4 
      FROM (SELECT '2011-02-17' AS dt, @i := 0, @prev_tn := NULL) s 
      JOIN m1 m 
      ON m.c1 <= s.dt 
      ORDER BY s.dt, m.c2, m.c1 DESC 
     ) o 
GROUP BY o.tn, o.dt 
HAVING SUM(1) >= 3 

(HAVING子句保证了查询返回的结果只有当至少有三排给定测试,在指定日期前。)下面是该查询输出两个不同的日期,第17和20:

Test Date  R R2  R3  R4 
------ ---------- -- ------ ------ ----- 
Test-A 2011-02-17 48 -52.96 -0.96 40.33 
Test-B 2011-02-17 64 -38.28 12.72 39.67 
Test-C 2011-02-17 55 -4.35 -41.35 37.00 

Test Date  R R2  R3  R4 
------ ---------- -- ------ ------ ----- 
Test-A 2011-02-20 31 -40.87 -56.87 41.67 
Test-B 2011-02-20 34 -56.18 -45.18 45.33 
Test-C 2011-02-20 17 -51.09 -13.09 28.67 

(查询会稍微复杂,要获得一个以上的日期结果)

这可能不是解决问题的最好方法,但我已经成功了与MySQL一起使用这种方法。