链接SQL查询

时间:2011-09-06 19:07:18

标签: mysql sql

现在我正在运行

SELECT formula('FOO') FROM table1
WHERE table1.foo = 'FOO' && table1.bar = 'BAR';

但我希望不是在常量FOO上运行,而是在查询中的每个值上运行

SELECT foos FROM table2
WHERE table2.bar = 'BAR';

我该怎么做?

编辑:重要更改:将FOO添加到函数的参数中。

插图:

SELECT foo FROM table1 WHERE foo = 'FOO' && table1.bar = 'BAR';

给出一个具有FOOa,FOOb,FOOc的列。

SELECT formula('FOO') FROM table1
WHERE table1.foo = 'FOO' && table1.bar = 'BAR';

给出一个条目,比如sum(FOO)(实际上要复杂得多,但它在某些时候使用聚合来组合结果)。

我想要一些查询,其给出具有和(FOO1),和(FOO2),......的列,其中每个FOOn以与FOO类似的方式计算。但我想用一个查询而不是 n 查询来执行此操作(因为 n 可能很大,并且在任何情况下,FOOn的特定值因具体情况而异)

4 个答案:

答案 0 :(得分:9)

试试这个:

SELECT formula FROM table1
WHERE table1.foo IN(SELECT foos FROM table2
WHERE table2.bar = 'BAR';
) AND table1.bar = 'BAR';

答案 1 :(得分:2)

SELECT formula FROM table1 WHERE bar = 'BAR' AND foo IN (SELECT foos FROM table2 WHERE bar = 'BAR');

编辑:

这未经过测试,但也许这会有用吗?

SELECT formula(q1.foo) FROM table1 INNER JOIN (SELECT foo, bar FROM table2) q1 ON table1.foo = q1.foo WHERE table1.bar = 'BAR';

答案 2 :(得分:1)

您必须使用dynamic SQL statements 这种方式的工作方式是您只需使用参数将SQL语句串在一起。

虽然不允许用户提供该数据,但您需要小心,因为转义不能保护您免受SQL注入。您需要针对白名单检查每个列名称。

这是存储过程中的示例代码。

这样做的方法是,你有一个带有列名的(临时)表,存储过程将它构建到一个查询中:

dynamic  /*holds variable parts of an SQL statement
-----------
id integer PK
column_name varchar(255)
operation ENUM('what','from','where','group by','having','order by','limit')
function_name varchar(255)  /*function desc with a '@' placeholder where  */
                            /* the column-name goes  */

whitelist /*holds all allowed column names*/
-----------
id integer PK
allowed varchar(255)  /*allowed column of table name*/
item ENUM('column','table')

动态SQL存储过程。预计会有两个表:dynamicwhitelist预填充。

DELIMITER $$

CREATE PROCEDURE dynamic_example;
BEGIN
  DECLARE vwhat VARCHAR(65000);
  DECLARE vfrom VARCHAR(65000);
  DECLARE vwhere VARCHAR(65000);
  DECLARE vQuery VARCHAR(65000);

  SELECT group_concat(REPLACE(function_name,'@',column_name)) INTO vwhat 
    FROM dynamic
    INNER JOIN whitelist wl ON (wl.allowed LIKE column_name 
                                AND wl.item = 'column') 
    WHERE operation = 'what' AND  
  SELECT group_concat(REPLACE(function_name,'@',column_name)) INTO vfrom 
    FROM dynamic 
    INNER JOIN whitelist wl ON (wl.allowed LIKE column_name
                                AND wl.item = 'table')  
    WHERE operation = 'from';
  SELECT group_concat(REPLACE(function_name,'@',column_name)) INTO vwhere
    FROM dynamic 
    INNER JOIN whitelist wl ON (wl.allowed LIKE column_name
                                AND wl.item = 'column')  
    WHERE operation = 'where';
  IF vwhat IS NULL THEN SET vwhat = ' * ';
  IF vwhere IS NOT NULL THEN SET vwhere = CONCAT(' WHERE ',vwhere); END IF;

  SET vQuery = CONCAT(' SELECT ',vwhat,' FROM ',vfrom,IFNULL(vwhere,''));
  PREPARE dSQL FROM vQuery;
  EXECUTE dSQL;
  DEALLOCATE PREPARE dSQL;     
END $$

DELIMITER ;

答案 3 :(得分:0)

尝试:

SELECT formula FROM table1, table2
WHERE table1.foo = table2.foo AND table1.bar = table2.bar;