MySQL查询中的复杂WHERE子句 - [在MySQL中使用VLOOKUP]

时间:2012-03-20 04:13:51

标签: mysql sql

我有一个包含以下表格的数据库(括号中为with sample data):

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以返回匹配的公司。但是,我找不到解析一些简单查询的解决方案。

EG。用户查询:

Sales_2012 > 1.1 * Sales_2012 AND
CAGR > 13

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

解析上面的主要问题: 我计划将用户查询中的所有比率名称替换为companies_ratios中的值。但是,我需要交叉引用行数据。对于每个ratio_name ,我需要value where ratio_id = x之类的内容。它可能类似于excel中的vlookup(将行数据用作列)。

1 个答案:

答案 0 :(得分:1)

我已经能够根据您提供的结构创建一个存储过程,该结构从字符串返回公司ID。它有点复杂,可能需要其他人审查它,但它似乎提供了正确的结果。

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$$    

我使用以下网站来协助创建查询。他们应该能够更多地解释函数,但基本上它遍历比率表,当它在用户查询中找到比率名称时,它用select语句替换它。结果语句在最后连接在一起以创建最终的select语句,然后执行该语句,提供唯一公司ID的列表。

执行STRING作为查询 - 动态SQL - > PREPARE
http://forums.mysql.com/read.php?60,27979,30437

MySQL论坛::存储过程:: MySQL存储过程教程
http://forums.mysql.com/read.php?98,358569,358569

MySQL游标
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

创建过程并创建函数语法
http://dev.mysql.com/doc/refman/5.0/en/create-procedure.html