0

我有一张银行交易表,其中包含 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”事务的总和是错误的,因为它也将“amazon”事务相加。

我希望交易的选择总和是互斥的或类似的东西,以便每个交易只是上述 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');
4

4 回答 4

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
于 2011-08-27T13:24:53.477 回答
1

您正在搜索包含mazo. 如果您只想要 Mazo,请更改:

SUM(IF(description LIKE '%mazo%',cashOut,0)) AS Mazo,

SUM(IF(description = 'mazo',cashOut,0)) AS Mazo,

编辑:在回复您的评论时,您可以使用正则表达式[[:<:]]来搜索单词边界

SUM(IF(description REGEXP '[[:<:]]mazo[[:>:]]',cashOut,0)) AS Mazo,
于 2011-08-27T12:13:49.790 回答
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
于 2011-08-27T12:39:13.170 回答
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
于 2011-08-27T12:18:48.140 回答