2011-02-17 54 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一起使用這種方法。