在MySQL中的SELECT中的IF语句SQL查询

时间:2014-08-25 13:46:02

标签: mysql sql select stored-procedures group-by

我有以下存储过程,工作正常。

CREATE DEFINER=`root`@`localhost` PROCEDURE `TxCountByDatePerod`(IN `fromdate` DATE, IN `todate` DATE, IN `department` VARCHAR(20), IN `status` VARCHAR(10), IN `ipg` VARCHAR(20))
SELECT d.dept_name,
       s.service_name,
       COUNT(*) AS all_row_count
FROM department AS d
INNER JOIN service s ON s.dept_id=d.dept_id
INNER JOIN transaction_detail t ON s.dept_id=t.dept_id
AND s.service_id=t.service_id
WHERE t.tx_begin_date BETWEEN fromdate AND todate
  AND (t.dept_id = department
       OR department ='null')
  AND (t.tx_status = status
       OR status ='null')
  AND (t.pg_name = ipg
       OR ipg ='null')
GROUP BY t.dept_id,
         t.service_id

上面的SP是用MySQL编写的,用于获取特定部门的特定服务提供的给定持续时间的事务数。交易可以是3种不同的交易状态(tx_status coulmn),它们已完成(1),失败(-1),未完成(0)。

我要做的是获取下面报告的数据。

enter image description here

现在的问题是所有状态都分为一行。我尝试了下面的SQL来根据需要获取数据,但是它给出了一个错误,即语法不正确。

CREATE DEFINER=`root`@`localhost` PROCEDURE `TxCountByDatePerod`(IN `fromdate` DATE, IN `todate` DATE, IN `department` VARCHAR(20), IN `status` VARCHAR(10), IN `ipg` VARCHAR(20))
SELECT d.dept_name,
       s.service_name,
       COUNT(*) AS all_row_count,
       IF(t.tx_status = 1,
          SELECT COUNT(*)
          FROM transaction_detail
          WHERE tx_status = 1) AS successful_tx_count
FROM department AS d
INNER JOIN service s ON s.dept_id=d.dept_id
INNER JOIN transaction_detail t ON s.dept_id=t.dept_id
AND s.service_id=t.service_id
WHERE t.tx_begin_date BETWEEN fromdate AND todate
  AND (t.dept_id = department
       OR department ='null')
  AND (t.tx_status = status
       OR status ='null')
  AND (t.pg_name = ipg
       OR ipg ='null')
GROUP BY t.dept_id,
         t.service_id

请参阅下面的附加行。

IF(t.tx_status = 1, SELECT COUNT(*) FROM transaction_detail WHERE tx_status = 1) AS successful_tx_count is added to the SP.

我该如何解决这个问题?

2 个答案:

答案 0 :(得分:4)

使用带有select的IF语句的正确语法就像这样

CREATE DEFINER=`root`@`localhost` PROCEDURE `TxCountByDatePerod`(IN `fromdate` DATE, IN `todate` DATE, IN `department` VARCHAR(20), IN `status` VARCHAR(10), IN `ipg` VARCHAR(20))
SELECT d.dept_name,
       s.service_name,
       COUNT(*) AS all_row_count,
       IF(t.tx_status = 1, 
          (SELECT COUNT(*) FROM transaction_detail WHERE tx_status = 1), 
          0 
         ) AS successful_tx_count
FROM department AS d
INNER JOIN service s ON s.dept_id=d.dept_id
INNER JOIN transaction_detail t ON s.dept_id=t.dept_id
AND s.service_id=t.service_id
WHERE t.tx_begin_date BETWEEN fromdate AND todate
  AND (t.dept_id = department
       OR department ='null')
  AND (t.tx_status = status
       OR status ='null')
  AND (t.pg_name = ipg
       OR ipg ='null')
GROUP BY t.dept_id,
         t.service_id

注意:

我只是输入一个默认的0值,因为你正在计算,但你可以改变它

IF(t.tx_status = 1
    ,(SELECT COUNT(*) FROM transaction_detail WHERE tx_status = 1)
    ,0 -- # -- this can be anything.. you could put in NULL or whatever else if you want
  ) AS successful_tx_count

您也可以使用用户定义的变量并将其插入,如此

SET @a := (SELECT COUNT(*) FROM transaction_detail WHERE tx_status = 1);

然后在if语句中插入@a变量,如此

if(t.tx_status = 1, @a, 0)

有关if函数

的更多详细信息,请参阅此ARTICLE

答案 1 :(得分:2)

这是您的select声明:

SELECT d.dept_name,
       s.service_name,
       COUNT(*) AS all_row_count,
       IF(t.tx_status = 1,
          SELECT COUNT(*)
          FROM transaction_detail
          WHERE tx_status = 1) AS successful_tx_count

为什么在这里使用子查询?我怀疑你想要"成功"计数以匹配与where相同的条件(来自count(*)子句)。所以,只需使用条件聚合:

SELECT d.dept_name,
       s.service_name,
       COUNT(*) AS all_row_count,
       SUM(t.tx_status = 1) AS successful_tx_count