2012-03-09 114 views
2

我試圖將我的問題簡化爲我在下面寫下的一個基本示例,實際問題更加複雜,因此下面的查詢可能沒有太大意義,但基本概念是相同的(數據從一個查詢到另一個查詢)。將一個查詢的結果輸入另一個查詢

查詢1:

SELECT Ping.ID as PingID, Base.ID as BaseID FROM 
    (SELECT l.ID, mg.DateTime from list l 
    JOIN mygroup mg ON mg.ID = l.MyGroup 
    WHERE l.Type = "ping" 
    ORDER BY l.ID DESC 
    ) Ping 
    INNER JOIN 
    (SELECT l.ID, mg.DateTime from list l 
    JOIN mygroup mg ON mg.ID = l.MyGroup 
    WHERE l.Type = "Base" 
    ORDER BY l.ID DESC 
    ) Base 
    ON Base.DateTime < Ping.DateTime 
    GROUP BY Ping.ID 
    ORDER BY Ping.ID DESC; 

+--------+--------+ 
| PingID | BaseID | 
+--------+--------+ 
|  11 |  10 | 
|  9 |  8 | 
|  7 |  6 | 
|  5 |  3 | 
|  4 |  3 | 
+--------+--------+ 

//從下面我需要通過PingID以上和10由上文了baseid然後將結果替換11,如果沒有結果顯示在上文第三列(0, 1個,如果結果)

查詢2:

SELECT * FROM 
    (SELECT sl.Data FROM list l 
    JOIN sublist sl ON sl.ParentID = l.ID 
    WHERE l.Type = "ping" AND l.ID = 11) Ping 
    INNER JOIN 
    (SELECT sl.Data FROM list l 
    JOIN sublist sl ON sl.ParentID = l.ID 
    WHERE l.Type = "base" AND l.ID = 10) Base 
    ON Base.Data < Ping.Data; 

我怎樣才能做到這一點?再次,我不確定我會收到什麼樣的建議,但請理解查詢2實際上超過200行,而且我基本無法觸及它,因此我沒有那麼大的靈活性,因爲我想和理想情況下我想在SQL中完成所有工作,而不必編寫腳本。

CREATE DATABASE lookback; 
use lookback; 

CREATE TABLE mygroup (
ID       BIGINT NOT NULL AUTO_INCREMENT PRIMARY KEY, 
DateTime     DateTime  
) ENGINE=InnoDB; 

CREATE TABLE list (
ID       BIGINT NOT NULL AUTO_INCREMENT PRIMARY KEY, 
Type      VARCHAR(255), 
MyGroup      BIGINT NOT NULL, 
Data      INT NOT NULL 
) ENGINE=InnoDB; 

CREATE TABLE sublist (
ID       BIGINT NOT NULL AUTO_INCREMENT PRIMARY KEY, 
ParentID     BIGINT NOT NULL, 
Data      INT NOT NULL 
) ENGINE=InnoDB; 

INSERT INTO mygroup (DateTime) VALUES ("2012-03-09 22:33:19"), ("2012-03-09 22:34:19"), ("2012-03-09 22:35:19"), ("2012-03-09 22:36:19"), ("2012-03-09 22:37:19"), ("2012-03-09 22:38:19"), ("2012-03-09 22:39:19"), ("2012-03-09 22:40:19"), ("2012-03-09 22:41:19"), ("2012-03-09 22:42:19"), ("2012-03-09 22:43:19");  
INSERT INTO list (Type, MyGroup, Data) VALUES ("ping", 1, 4), ("base", 2, 2), ("base", 3, 4), ("ping", 4, 7), ("ping", 5, 8), ("base", 6, 7), ("ping", 7, 8), ("base", 8, 3), ("ping", 9, 10), ("base", 10, 2), ("ping", 11, 3); 
INSERT INTO sublist (ParentID, Data) VALUES (1, 2), (2, 3), (3, 6), (4, 8), (5, 4), (6, 5), (7, 1), (8, 9), (9, 11), (10, 4), (11, 6); 
+2

SQL搗鼓以上:http://sqlfiddle.com/#!2/c6781/1 – 2012-03-09 23:07:53

+0

非常酷的感謝! – user391986 2012-03-12 18:24:54

+0

謝謝大家,我用這個答案學了一大堆東西,不幸的是沒有人完成這個工作,所以在擺弄了一些東西之後,我找到了一個可行的解決方案!我基本上創建了查詢2的存儲過程,然後從查詢1中添加了一個額外的參數,它將SELECT Ping.ID稱爲PingID,Base.ID作爲BaseID,(SELECT fnc_callquerytwo(PingID,BaseID))FROM – user391986 2012-03-12 18:54:08

回答

4

處理這個問題最簡單的方法是臨時表,描述herehere。如果你創建一個空表來存儲你的結果(我們稱之爲tbl_temp1),你可以這樣:

INSERT INTO tbl_temp1 (PingID, BaseID) 
SELECT Ping.ID as PingID, Base.ID as BaseID 
FROM ... 

然後你就可以查詢它,只要你喜歡:

SELECT PingID, BaseID from tbl_temp1 ... 

編輯補充:

從文檔的CREATE TEMPORARY TABLE

You can use the TEMPORARY keyword when creating a table. A TEMPORARY table is visible only to the current connection, and is dropped automatically when the connection is closed. This means that two different connections can use the same temporary table name without conflicting with each other or with an existing non-TEMPORARY table of the same name. (The existing table is hidden until the temporary table is dropped.)

+0

現在試一下,臨時表是否需要每次手動清零,有沒有可能兩次運行得到數據混合? – user391986 2012-03-12 18:29:19

4

如果這是一個更扁平的查詢,那麼會有一個直接的答案。

當然可以使用派生表作爲外部查詢的輸入。一個簡單的例子是:

select 
    data1, 
    (select data3 from howdy1 where howdy1.data1 = greetings.data1) data3_derived 
from 
    (select data1 from hello1 where hello1.data2 < 4) as greetings; 

其中派生表greetings在直列式查詢中使用。 (SQL搗鼓這個簡單的例子:http://sqlfiddle.com/#!3/49425/2

按照這一邏輯將導致我們假設你可以投你的第一個查詢爲query1派生表,然後重鑄query2到select語句。

對於我構造的以下內容:

select query1.pingId, query1.baseId, 
     (SELECT ping.Data pingData FROM 
     (SELECT sl.Data FROM list l 
      JOIN sublist sl ON sl.ParentID = l.ID 
      WHERE l.Type = "ping" AND l.ID = query1.pingId 
     ) Ping 
     INNER JOIN 
     (SELECT sl.Data FROM list l 
      JOIN sublist sl ON sl.ParentID = l.ID 
      WHERE l.Type = "base" AND l.ID = query1.baseId 
     ) Base 
     ON Base.Data < Ping.Data) 
from 
    (SELECT Ping.ID as PingID, Base.ID as BaseID FROM 
     (SELECT l.ID, mg.DateTime from list l 
     JOIN mygroup mg ON mg.ID = l.MyGroup 
     WHERE l.Type = "ping" 
     ORDER BY l.ID DESC 
    ) Ping 
    INNER JOIN 
    (SELECT l.ID, mg.DateTime from list l 
     JOIN mygroup mg ON mg.ID = l.MyGroup 
     WHERE l.Type = "Base" 
     ORDER BY l.ID DESC 
    ) Base 
    ON Base.DateTime < Ping.DateTime 
    GROUP BY Ping.ID 
    ) query1 
    order by pingId desc; 

其中I已插入到query2query1 select子句和代替分別1110,插入query1.pingIdquery1.baseId。如果11和10保留在原位,則此查詢有效(但顯然只爲每行生成相同的數據)。

但是,當這個執行時,我給出了一個錯誤:Unknown column 'query1.pingId'。顯然,在嵌套的派生表中不能看到query1。

因爲一般來說,這種類型的查詢是可能的,所以當嵌套深度只有1層時(根據我頂部的問候示例),必須存在邏輯限制,爲什麼這個嵌套層次不是可能。 (時間拉出數據庫理論書...)

如果我遇到了這個問題,我會重寫和扁平查詢來獲得我想要的真實數據。並且消除一些東西,包括在query1中使用的非常討厭的group by,以獲得給定pingId的最大baseId。

你說這是不可能的,由於外部約束。所以,這最終是一個沒有答案的答案。不是很有用,但也許值得一試。

(SQL搗鼓這一切:http://sqlfiddle.com/#!2/bac74/35

+0

啊太糟糕了,這將是完美的! – user391986 2012-03-12 18:21:55

+0

+1使用sqlfiddle – pal4life 2014-07-31 16:45:21

1

如果您不能修改查詢2,那麼有什麼我們可以建議。這是您的兩個查詢與降低的嵌套級別的組合。我懷疑這將是一個大的數據集慢 -

SELECT tmp1.PingID, tmp1.BaseID, IF(slb.Data, 1, 0) AS third_col 
FROM (
    SELECT lp.ID AS PingID, MAX(lb.ID) AS BaseID 
    FROM MyGroup mgp 
    INNER JOIN MyGroup mgb 
    ON mgb.DateTime < mgp.DateTime 
    INNER JOIN list lp 
    ON mgp.ID = lp.MyGroup 
    AND lp.Type = 'ping' 
    INNER JOIN list lb 
    ON mgb.ID = lb.MyGroup 
    AND lb.Type = 'base' 
    GROUP BY lp.ID DESC 
) AS tmp1 
LEFT JOIN sublist slp 
    ON tmp1.PingID = slp.ParentID 
LEFT JOIN sublist slb 
    ON tmp1.BaseID = slb.ParentID 
    AND slb.Data < slp.Data; 
+0

感謝nnichols,不幸的是查詢2太複雜,無法擺弄,這是我必須處理的可悲現實。 – user391986 2012-03-12 18:56:10

相關問題