我认为函数的MySQL逻辑

时间:2013-05-15 15:13:49

标签: mysql if-statement logic where

我有大约500行带有simliar数据到下面的4行,从这个例子我只想要使用以下逻辑返回两行:

如果emp No 817 sal_id = 2 is_active 0则返回817 sal_id 1或IF emp No 820 sal_id = 2 is_active 1然后返回820 sal_2

默认情况下,sal_id 1始终处于有效状态,如果sal_id为1,则应返回sal_id 2而不是is_active 1,希望这有意义!

+--------+--------+-----------+-----------------------+-----------+
| emp No | sal_id |   value   |    effective_date     | is_active |
+--------+--------+-----------+-----------------------+-----------+
|    817 |      1 | DED914E3B | 01/04/2013            |         1 |
|    817 |      2 | 0         | 0                     |         0 |
|    820 |      1 | 8238942BE | 02/04/2013            |         1 |
|    820 |      2 | EA42574E4 | 02/04/2013            |         1 |
+--------+--------+-----------+-----------------------+-----------+

给我一​​个结果:

+--------+--------+-----------+----------------+-----------+
| emp No | sal_id |   value   | effective_date | is_active |
+--------+--------+-----------+----------------+-----------+
|    817 |      1 | DED914E3B | 01/04/2013     |         1 |
|    820 |      2 | EA42574E4 | 02/04/2013     |         1 |
+--------+--------+-----------+----------------+-----------+

不确定甚至可以做到这一点,请提出建议并表示感谢。

2 个答案:

答案 0 :(得分:0)

假设数据存储在employee_salary中,这是一个肮脏的黑客;

select es.emp_no, es.sal_id, value, effective_date, is_active from employee_salary es
join ( 
     select emp_no, max(sal_id) as sal_id from employee_salary
         where is_active<>0
         group by emp_no
) selector
where es.emp_no=selector.emp_no and es.sal_id=selector.sal_id

限制:

  • 在不重写SQL的情况下,将默认值从2更改为1并不容易。
  • 我不清楚如果数据不在表中而是SELECT的结果,而不是临时表,这种方法将如何应用。
  • 根据需要,可能无法处理is_active=0 {/ strong> sal_id=1sal_id=2的情况,目前没有为该emp_no返回任何结果,这是什么你想要吗?
  • 正如Aya所指出的,这会生成一个临时表,然后在不使用索引的情况下进行排序,预计这会很慢。

答案 1 :(得分:0)

这个解决方案比Mark更详细,但应该更高效,因为它避免使用临时表......

SELECT
    es1.emp_no,
    IF(es2.is_active=1, es2.sal_id, es1.sal_id) AS sal_id,
    IF(es2.is_active=1, es2.value, es1.value) AS value,
    IF(es2.is_active=1, es2.effective_date, es1.effective_date) AS effective_date,
    IF(es2.is_active=1, es2.is_active, es1.is_active) AS is_active
FROM employee_salary es1
    LEFT JOIN employee_salary es2 ON (es2.emp_no=es1.emp_no AND es2.sal_id=2)
WHERE es1.sal_id=1;

......产生......

+--------+--------+-----------+----------------+-----------+
| emp_no | sal_id | value     | effective_date | is_active |
+--------+--------+-----------+----------------+-----------+
|    817 |      1 | DED914E3B | 01/04/2013     |         1 |
|    820 |      2 | EA42574E4 | 02/04/2013     |         1 |
+--------+--------+-----------+----------------+-----------+

......并且EXPLAIN产生......

+----+-------------+-------+------+---------------+------+---------+------+------+-------------+
| id | select_type | table | type | possible_keys | key  | key_len | ref  | rows | Extra       |
+----+-------------+-------+------+---------------+------+---------+------+------+-------------+
|  1 | SIMPLE      | es1   | ALL  | NULL          | NULL | NULL    | NULL |    4 | Using where |
|  1 | SIMPLE      | es2   | ALL  | NULL          | NULL | NULL    | NULL |    4 |             |
+----+-------------+-------+------+---------------+------+---------+------+------+-------------+

......与马克的相比......

+----+-------------+-----------------+------+---------------+------+---------+------+------+----------------------------------------------+
| id | select_type | table           | type | possible_keys | key  | key_len | ref  | rows | Extra                                        |
+----+-------------+-----------------+------+---------------+------+---------+------+------+----------------------------------------------+
|  1 | PRIMARY     | <derived2>      | ALL  | NULL          | NULL | NULL    | NULL |    2 |                                              |
|  1 | PRIMARY     | es              | ALL  | NULL          | NULL | NULL    | NULL |    4 | Using where; Using join buffer               |
|  2 | DERIVED     | employee_salary | ALL  | NULL          | NULL | NULL    | NULL |    4 | Using where; Using temporary; Using filesort |
+----+-------------+-----------------+------+---------------+------+---------+------+------+----------------------------------------------+

您可以删除任何实际上不需要这些值的IF子句。