简体   繁体   中英

IF statement SQL query within the SELECT in MySQL

I have the below stored procedure which works fine.

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

Above SP is written in MySQL to get the number of transactions for a given time duration, provided by a particular service of a particular department. A transactions can be 3 different transaction statuses( tx_status coulmn) which are completed(1), failed(-1), uncompleted(0).

What I'm trying to do is get the data for the report below.

在此处输入图片说明

The right now the problem is that all the status are grouped into one row. I tried the below SQL to get the data as needed but it gives out an error that the syntax is not correct.

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

Please see the added line below.

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

How can I fix this?

the correct syntax for using an IF statement with a select is like this

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

NOTE:

I just put in a default 0 value since you are doing a count but you can change that

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

you can also use a user defined variable and plug that in like so

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

and then plug the @a variable in your if statement like so

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

See this ARTICLE for more details on the if function

This is your select statement:

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

Why are you using a subquery here? I suspect that you want the "successful" count to match the same conditions (from the where clause) as the count(*) . So, just use conditional aggregation:

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

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM