alimentar el resultado de una consulta a otra

I tried to simplify my question to a basic example I wrote down below, the actual problem is much more complex so the below queries might not make much sense but the basic concepts are the same (data from one query as argument to another).

Consulta 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 |
+--------+--------+

// from below I need to replace 11 by PingID above and 10 by BaseID above then the results to show up on as third column above (0 if no results, 1 if results)

Consulta 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;

How can I do this? Again I'm not sure what kind of advice I will receive but please understand that the Query 2 is in reality over 200 lines and I basically can't touch it so I don't have so much flexibility as I'd like and ideally I'd like to get this working all in SQL without having to script this.

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);

preguntado el 09 de marzo de 12 a las 22:03

SQL Fiddle for the above: sqlfiddle.com/#!2/c6781/1 -

Thanks everyone I learned a bunch of things with the answers unfortunately none were complete to make this work so after fiddling around some more I just found a solution that works! I basically created a stored procedure for Query 2 then from query 1 I just added an extra argument in the SELECT that calls it SELECT Ping.ID as PingID, Base.ID as BaseID, (SELECT fnc_callquerytwo(PingID, BaseID)) FROM -

If query2 is unchangeable, that's probably for the best. I had tried a temp table, feeding it in the same way as I fed query1 into my answer and I still got the unknown column error. -

3 Respuestas

The simplest way of dealing with this is temporary tables, described aquí y aquí. If you create an empty table to store your results (let's call it tbl_temp1) you can to this:

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

Then you can query it however you like:

SELECT PingID, BaseID from tbl_temp1 ...

Editado para agregar:

De los documentos para CREAR TABLA TEMPORAL:

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.)

respondido 12 mar '12, 22:03

trying this now, does the temporary table need to get cleared manually every time, is there a possible for two runs to get data mixed up? - user391986

If this were a more flattened query, then there would a straightforward answer.

It is certainly possible to use a derived table as the input to outer queries. A simple example would be:

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

where the derived table greetings is used in the inline query. (SQL Fiddle for this simplistic example: http://sqlfiddle.com/#!3/49425/2 )

Following this logic would lead us to assume that you could cast your first query as a derived table of query1 and then recast query2 into the select statement.

For that I constructed the following:

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;

where I have inserted query2 into a select clause from query1 e insertado query1.pingId y query1.baseId en lugar de 11 y 10, respectively. If 11 and 10 are left in place, this query works (but obviously only generates the same data for each row).

But when this is executed, I'm given an error: Unknown column 'query1.pingId'. Obviously, query1 cannot be seen inside the nested derived tables.

Since, in general, this type of query is possible, when the nesting is only 1 level deep (as per my greeting example at the top), there must be logical restrictions as to why this level of nesting isn't possible. (Time to pull out the database theory book...)

If I were faced with this, I'd rewrite and flatten the queries to get the real data that I wanted. And eliminate a couple things including that really nasty group by that is used in query1 to get the max baseId for a given pingId.

You say that's not possible, due to external constraints. So, this is, ultimately, a non-answer answer. Not very useful, but maybe it'll be worth something.

(SQL Fiddle for all this: http://sqlfiddle.com/#!2/bac74/35 )

respondido 10 mar '12, 04:03

ah too bad that would have been perfect! - user391986

If you cannot modify query 2 then there is nothing we can suggest. Here is a combination of your two queries with a reduced level of nesting. I suspect this would be slow with a large dataset -

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;

respondido 10 mar '12, 17:03

Thanks nnichols, unfortunately query 2 is too complex to fiddle around with, a sad reality that I must deal with. - user391986

No es la respuesta que estás buscando? Examinar otras preguntas etiquetadas or haz tu propia pregunta.