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

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

例如。用户查询:

Sales_2012 > 1.1 * Sales_2012 AND
CAGR > 13

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

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

最佳答案

我已经能够根据您提供的结构创建一个存储过程,该结构从字符串返回公司 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 语句。生成的语句在最后连接在一起以创建最终的选择语句,然后执行该语句,提供唯一公司 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

CREATE PROCEDURE 和 CREATE FUNCTION 语法
http://dev.mysql.com/doc/refman/5.0/en/create-procedure.html

关于mysql - MySQL 查询中的复杂 WHERE 子句 - [在 MySQL 中使用 VLOOKUP],我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/9781263/

相关文章:

mysql - WHERE 子句中 varchar 列的奇怪行为

mysql - 捕捉时间范围

sql - 使用动态行和列创建 PIVOT - SQL Server 2016

sql - 标量函数中的 CTE

mysql - 获取 id 数

sql - 将 WHERE 条件转换为 LEFT JOIN

mysql - 检查 IP 是否在 CIDR 网络掩码(范围)内

php - 手动将mysql查询结果缓存到txt文件

mysql - ASP Classic 和 MYSQL 是否可以跨多种语言设置数字格式?

java - 从java运行oracle sql脚本