【问题标题】:mysql group_concat and group by not workingmysql group_concat 和 group by 不工作
【发布时间】:2020-06-16 15:33:45
【问题描述】:

我有以下两张表(简体):

tblinvoices

id  dateCreated    

1   2020-01-02
2   2020-01-03
3   2020-01-03
4   2020-01-04

tblinvoicesLines

id invoiceId vatId vatAmount
1  4         7     35.50
2  4         8     15.75
3  4         7     11.50
3  5         7     10.05
4  6         7     11.04

我正在尝试在输出中汇总 vatAmount 结果,例如以下示例:

invoiceId   listVatAmounts
4          47.00,15.75
5          10.05
6          11.04

我有以下 mysql 查询:

select
tblInvoices.id as invoiceId,

(
select group_concat(vatAmount) from tblinvoicesLines
where tblinvoicesLines.invoiceId=tblInvoices.id
group by tblinvoicesLines.vatId
) as listVatAmounts

from tblInvoices
order by id desc
limit 10

我希望 group by tblinvoicesLines.vatId 将这些值组合在一起,但 mysql 返回错误:

子查询返回多于 1 行

我可以做些什么来达到预期的效果?我希望通过子查询来实现。

【问题讨论】:

  • 您似乎只需要一张桌子就可以做到这一点> tblinvoicesLines
  • '我希望通过子查询来实现' - 为什么?单独使用 group_Concat 是不合适的,因为您似乎是先按 vatid 对增值税金额求和
  • 为什么按vatId分组
  • 您需要一个聚合(每张发票的增值税列表以逗号分隔)(每张发票的增值税总额和增值税 ID)。这是两个步骤。

标签: mysql sql group-by group-concat


【解决方案1】:

您需要先执行vatId 的求和,然后您可以列出invoiceIdvatAmount 求和:

SELECT invoiceId, GROUP_CONCAT(sumVatAmounts) AS listVatAmounts
FROM (SELECT invoiceId, vatId, SUM(vatAmount) AS sumVatAmounts
      FROM tblinvoicesLines
      GROUP BY invoiceId, vatId) t
GROUP BY invoiceId

输出:

invoiceId   listVatAmounts
4           47.00,15.75
5           10.05
6           11.04

如果您需要包含来自tblInvoices 的值,您可以将JOIN 该表作为派生表添加到上述查询中:

SELECT i.id AS invoiceId, i.dateCreated, GROUP_CONCAT(t.sumVatAmounts) AS listVatAmounts
FROM tblInvoices i
LEFT JOIN (SELECT invoiceId, vatId, SUM(vatAmount) AS sumVatAmounts
           FROM tblinvoicesLines
           GROUP BY invoiceId, vatId) t ON t.invoiceId = i.id
GROUP BY i.id, i.dateCreated

或者如果你真的必须使用子查询:

SELECT i.id AS invoiceId,
       (SELECT GROUP_CONCAT(sumVatAmounts)
        FROM (SELECT invoiceId, vatId, SUM(vatAmount) AS sumVatAmounts
              FROM tblinvoicesLines
              GROUP BY invoiceId, vatId) t
        WHERE t.invoiceId = i.id) AS listVatAmounts
FROM tblInvoices i

Demo on dbfiddle

【讨论】:

  • 感谢您的努力。在我的原始查询中,我必须保留“来自 tblInvoices”部分(出于各种原因),并且不能按照您建议的方式对 tblinvoicesLines 进行分组。它必须作为一个独立的子查询来实现
  • @user2022678 你能不能只把JOIN这个tblInvoices?例如dbfiddle.uk/…
  • @user2022678 请查看我的编辑。它提供了其他几个解决方案,包括子查询...
  • 谢谢尼克;你编辑效果很好!虽然它的性能相当缓慢。我刚刚在这里发布了一个“解决方案”。基本上它和你的一样,但我添加了一个变量 (addSign)invoiceId,出于性能原因,我曾经将它与 tblinvoicesLines.invoiceId 链接
  • @Patrick 是的 - 这就是使用子查询的问题,您不能将 invoiceId 值从顶层向下传递到足够深以使用它来过滤总和。使用变量是可行的,但有风险并且可能会停止工作,如果您更改查询足够多,因为 MySQL 不保证 SELECT 中值的评估顺序,因此有可能在分配之前评估子查询的@invoiceId。不过,如果它有效,您应该接受自己的答案。我仍然认为基于JOIN 的解决方案将是长期的最佳解决方案......
【解决方案2】:

您也可以像这样使用一个 SELECT 来做到这一点:

SELECT  invoiceId, CONCAT(
    SUM(IF(vatId=7,vatAmount,0))
    ,if( SUM(IF(vatId=8,vatAmount,0)) >0
        , CONCAT(',',SUM(IF(vatId=8,vatAmount,0)))
        ,'')
    ) AS listVatAmounts
FROM invoiceId
GROUP BY invoiceId;

OR 与子查询和所有 invoiceIds

SELECT
    invoiceId,
    GROUP_CONCAT(vatAmount ORDER BY vatId SEPARATOR ', ') AS listVatAmounts
FROM (
    SELECT id, invoiceId, vatId, SUM(vatAmount) as vatAmount
    FROM invoiceId
    GROUP BY invoiceId,vatId
    ) grp
GROUP BY invoiceId
ORDER BY id;

示例

MariaDB [bernd]> SELECT  invoiceId, CONCAT(
    ->     SUM(IF(vatId=7,vatAmount,0))
    ->     ,if( SUM(IF(vatId=8,vatAmount,0)) >0
    ->         , CONCAT(',',SUM(IF(vatId=8,vatAmount,0)))
    ->         ,'')
    ->     ) AS listVatAmounts
    -> FROM invoiceId
    -> GROUP BY invoiceId;
+-----------+----------------+
| invoiceId | listVatAmounts |
+-----------+----------------+
|         4 | 47.00,15.75    |
|         5 | 10.05          |
|         6 | 11.04          |
+-----------+----------------+
3 rows in set (0.01 sec)

MariaDB [bernd]>

示例 2

MariaDB [bernd]> SELECT
    ->     invoiceId,
    ->     GROUP_CONCAT(vatAmount ORDER BY vatId SEPARATOR ', ') AS listVatAmounts
    -> FROM (
    ->     SELECT id, invoiceId, vatId, SUM(vatAmount) as vatAmount
    ->     FROM invoiceId
    ->     GROUP BY invoiceId,vatId
    ->     ) grp
    -> GROUP BY invoiceId
    -> ORDER BY id;
+-----------+----------------+
| invoiceId | listVatAmounts |
+-----------+----------------+
|         4 | 47.00, 15.75   |
|         5 | 10.05          |
|         6 | 11.04          |
+-----------+----------------+
3 rows in set (0.00 sec)

MariaDB [bernd]>

【讨论】:

    【解决方案3】:

    我所做的如下:

    select
    @invoiceId:= tblInvoices.id as invoiceId,
    
    (
    select group_concat(vatAmount)
    from
    (
    select sum(vatAmount) as vatAmount
    from tblinvoicesLines
    where tblinvoicesLines.invoiceId=@invoiceId
    group by tblinvoicesLines.vatId
    ) t
    )
    
    as listVatAmounts
    
    from tblInvoices
    order by id desc
    limit 10
    

    但是性能不是很好。但是它在一个子查询中完成

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-07-10
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多