Цепные SQL-запросы - PullRequest
       2

Цепные SQL-запросы

6 голосов
/ 06 сентября 2011

Сейчас я запускаю

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 ]

9 голосов
/ 06 сентября 2011

Попробуйте это:

SELECT formula FROM table1
WHERE table1.foo IN(SELECT foos FROM table2
WHERE table2.bar = 'BAR';
) AND table1.bar = 'BAR';
2 голосов
/ 06 сентября 2011
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';
1 голос
/ 07 сентября 2011

Вам придется использовать динамические операторы SQL .
Это работает так, что вы просто связываете оператор 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. Предполагается, что две таблицы: dynamic и whitelist будут предварительно заполнены.

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 ;
0 голосов
/ 06 сентября 2011

Попробуйте:

SELECT formula FROM table1, table2
WHERE table1.foo = table2.foo AND table1.bar = table2.bar;
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...