Сложное предложение WHERE в запросе MySQL - [Использовать VLOOKUP в MySQL] - PullRequest
0 голосов
/ 20 марта 2012

У меня есть база данных со следующими таблицами ( с образцами данных в скобках):

companies {
    id: (1, 2, 3)
    company_name: ('Goog', 'Micr', 'Apple')
}

companies_ratios {
    company_id: (1, 1, 2, 1, 1)
    ratio_id: (1, 2, 1, 4, 5)
    value: (13, 9, 15, 5, 6)
}

ratios {
    id: (1, 2, 3, 4, 5)
    ratio_name: ('CAGR', 'Prf. Gwt', 'Sal. Gwt', 'Sales_2012', 'Sales_2011')
    ratio_formula: ('...')
    -- ratio_formula is not used at the moment
}

Мне нужно проанализировать пользовательский запрос в MySQL, чтобы получить соответствующие компании. Однако я не могу найти решение для анализа некоторых простых запросов.

Например. Пользовательские запросы:

Sales_2012 > 1.1 * Sales_2012 AND
CAGR > 13

Prf. Gwt > Sal. Gwt OR
CAGR > Prf. Gwt

Основная проблема при разборе выше: Я планирую заменить все имена отношений в пользовательском запросе их значением в companies_ratios. Тем не менее, Мне нужно перекрестные ссылки на данные строки. Мне нужно что-то вроде value where ratio_id = x для каждого имени_символа . Это может быть похоже на vlookup в Excel (использовать данные строки в качестве столбца).

1 Ответ

1 голос
/ 20 марта 2012

Мне удалось создать хранимую процедуру на основе предоставленной вами структуры, которая возвращает идентификатор компании из строки. Это немного сложно, и может потребоваться, чтобы другие просмотрели его, но, похоже, оно дает правильные результаты.

DELIMITER $$    
DROP PROCEDURE IF EXISTS sp_build_query $$        

CREATE PROCEDURE sp_build_query(IN userquery VARCHAR(100))    
BEGIN    

  DECLARE no_more_rows BOOLEAN;    
  DECLARE rname VARCHAR(50);    
  DECLARE fullsql VARCHAR(1000);    
  DECLARE ratio_cur CURSOR FOR SELECT ratio_name FROM ratios;    

  DECLARE CONTINUE HANDLER FOR NOT FOUND    
    SET no_more_rows = TRUE;    

  SET fullsql = userquery;    

   OPEN ratio_cur;    
   FETCH ratio_cur INTO rname;    
   rnamewhile: WHILE rname is not null DO    
     IF INSTR(fullsql, rname) > 0 THEN    
         SET fullsql = REPLACE(fullsql, rname, CONCAT(' (SELECT `value` FROM companies_ratios INNER JOIN ratios ON companies_ratios.ratio_id = ratios.id WHERE ratios.ratio_name = ''', rname , ''' AND companies_ratios.company_id = cr.company_id ) '));    
     END IF;    
     FETCH ratio_cur INTO rname;         
     IF no_more_rows THEN    
        CLOSE ratio_cur;    
        LEAVE rnamewhile;    
    END IF;    
   END WHILE rnamewhile;    


   SET @finalsql = CONCAT('SELECT company_id FROM companies_ratios cr WHERE ', fullsql , ' GROUP BY cr.company_id;');     

   PREPARE stmt1 FROM @finalsql;     
   EXECUTE stmt1;     
   DEALLOCATE PREPARE stmt1;     
END$$    

Для создания запроса я использовал следующие веб-сайты. Они должны быть в состоянии объяснить функции немного подробнее, но в основном он просматривает таблицу отношений и, когда он находит имя отношения в пользовательском запросе, заменяет его оператором выбора. Результирующий оператор объединяется в конце, чтобы создать ваш последний оператор выбора, который затем выполняется, предоставляя список уникальных идентификаторов компании.

Выполнить STRING как запрос - Динамический SQL -> ПОДГОТОВИТЬ
http://forums.mysql.com/read.php?60,27979,30437

Форумы MySQL :: Хранимые процедуры :: Учебник по хранимым процедурам MySQL
http://forums.mysql.com/read.php?98,358569,358569

MySQL Cursors
http://dev.mysql.com/doc/refman/5.0/en/cursors.html

Цикл в хранимых процедурах
http://www.mysqltutorial.org/stored-procedures-loop.aspx

Курсор SQL в хранимых процедурах
http://www.mysqltutorial.org/sql-cursor-in-stored-procedures.aspx

Синтаксис SQL для подготовленных операторов
http://dev.mysql.com/doc/refman/5.1/en/sql-syntax-prepared-statements.html

CREATE PROCEDURE и CREATE FUNCTION Синтаксис
http://dev.mysql.com/doc/refman/5.0/en/create-procedure.html

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...