我有一个包含列id,tDate,description,cashOut,cashIn的银行交易的表格。我想看看我是如何花钱的,特别是在亚马逊和一家名为Mazo的商店,所以我想得到这样的结果:
Month Amazon Mazo Total
1 100 200 300
我试过这个:
SELECT
MONTH(tDate) AS Month,
SUM(IF(description LIKE '%amazon%',cashOut,0)) AS Amazon,
SUM(IF(description LIKE '%mazo%',cashOut,0)) AS Mazo,
SUM(cashOut) AS Total
FROM `transactions`
GROUP BY Month
但是,我得到了以下内容:
Month Amazon Mazo Total
1 100 300 300
这个SQL查询的问题在于“mazo”交易的总和是错误的,因为它也加起来了“亚马逊”交易。
我希望选择要相互排斥的事务或类似的事务,以便每个事务只是上述一个SUM的一部分(不依赖于PHP或类似事件)。 (我的表包含的数据远远超过此数据,而且我有很多搜索条件,因此使用'%mazo%'作为搜索词是不够的。我需要一个解决问题的通用解决方案。)
有人有建议吗?
表及其数据的详细信息:
CREATE TABLE `transactions` (
`id` bigint(20) NOT NULL AUTO_INCREMENT,
`tDate` date NOT NULL,
`description` varchar(200) NOT NULL,
`cashOut` decimal(10,0) NOT NULL,
`cashIn` decimal(10,0) NOT NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB
INSERT INTO `transactions` (`id`, `tDate`, `description`, `cashOut`, `cashIn`) VALUES
(1, '2010-01-05', 'amazon', '100', '0'),
(4, '2010-01-15', 'mazo', '200', '0');
答案 0 :(得分:2)
您可以通过标记内部查询中的每一行,然后对其进行过滤来创建互斥组:
SELECT
MONTH(tDate) AS Month,
SUM(IF(flag = 'amazon', cashOut, 0)) AS Amazon,
SUM(IF(flag = 'mazo', cashOut, 0)) AS Mazo,
SUM(IF(flag = 'other', cashOut, 0)) AS Other,
SUM(cashOut) AS Total
FROM (
SELECT tDate, cashOut,
CASE
WHEN description LIKE '%amazon%' THEN 'amazon'
WHEN description LIKE '%mazo%' THEN 'mazo'
ELSE 'other'
END AS flag
FROM transactions
) x
GROUP BY Month
这样,如果某个事务匹配多个关键字,您将永远不会计算相同的事务两次。如果您不想在查询中重复两次相同的关键字,并且可以使用类似的列表:
Month What Sum
1 amazon 100
2 mazo 200
然后你可以使用:
SELECT
MONTH(tDate) AS Month,
flag AS What,
SUM(cashOut) AS Total
FROM (
SELECT tDate, cashOut,
CASE
WHEN description LIKE '%mazo%' THEN 'mazo'
WHEN description LIKE '%amazon%' THEN 'amazon'
ELSE 'other'
END AS flag
FROM transactions
) x
GROUP BY Month, flag
答案 1 :(得分:1)
您正在搜索包含mazo
的字符串。如果您只想要Mazo,请更改:
SUM(IF(description LIKE '%mazo%',cashOut,0)) AS Mazo,
到
SUM(IF(description = 'mazo',cashOut,0)) AS Mazo,
编辑:在回复您的评论时,您可以使用正则表达式[[:<:]]
搜索word boundaries:
SUM(IF(description REGEXP '[[:<:]]mazo[[:>:]]',cashOut,0)) AS Mazo,
答案 2 :(得分:1)
SELECT
MONTH(tDate) AS Month,
SUM(IF(description LIKE '%amazon%',cashOut,0)) AS Amazon,
SUM(IF(description LIKE '%mazo%' AND description NOT LIKE '%amazon%',cashOut,0)) AS Mazo,
SUM(cashOut) AS Total
FROM `transactions`
GROUP BY Month
答案 3 :(得分:0)
将=
与确切文字一起使用,而不是like
,只需丢失IF
即可。试试这个:
SELECT
MONTH(tDate) AS Month,
SUM((description = 'Amazon') * cashOut) AS Amazon,
SUM((description = 'Mazo') * cashOut) AS Mazo,
SUM(cashOut) AS Total
FROM `transactions`
GROUP BY Month