【问题标题】:Group_Concat with multiple joined tables具有多个连接表的 Group_Concat
【发布时间】:2021-06-20 00:42:57
【问题描述】:

我有两个包含活动预订的主要表格。 一个 Registrants 表(Bookings)R 和一个 Events 表 E。

还有两个连接表,Field_Values V 和 Event_Categories C

此图显示了关系

我要做的是创建一个反映用户购物车的发票查询。通常,用户会在一次交易中预订多个事件,因此我的发票应该包含常见项目的列,例如发票行项目值的用户名、用户电子邮件、预订日期、交易 ID 和聚合列,例如数量 "1,2" 描述 "Desc1, Desc2" 价格 "10.00, 20.00" 购物车中有两个订单项。

交易 ID (dcea4_eb_registrant.transaction_id) 对于每张发票都是唯一的,并且在该销售中每个行项目重复。

我有以下查询,它为每个行项目生成行

SELECT
  R.id as ID,
  E.event_date as ServiceDate,
  E.event_date - INTERVAL 1 DAY as DueDate,
  Concat('Ad-Hoc Booking:',E.title) as ItemProductService,
  Concat(R.first_name, ' ',R.last_name) as Customer,
  R.first_name as FirstName,
  R.last_name as LastName,
  R.email,
  R.register_date as InvoiceDate,
  R.amount as ItemAmount,
  R.comment,
  R.number_registrants as ItemQuantity,
  R.transaction_id as InvoiceNo,
  R.published as Status,
  
  
  E.event_date AS SERVICEDATE,
  Concat('Ad-Hoc Booking:',E.title) AS DESCRIPTION,
  R.number_registrants AS QUANTITY,
  FORMAT(R.amount / R.number_registrants,2) AS RATE,
  R.amount AS AMOUNT,
  C.category_id as CLASS,
  Concat(Group_Concat(V.field_value SEPARATOR ', '),'. ',R.comment) as Memo

FROM dcea4_eb_events E
LEFT JOIN dcea4_eb_registrants R  ON R.event_id = E.id
LEFT JOIN dcea4_eb_field_values V ON V.registrant_id = R.id
LEFT JOIN dcea4_eb_event_categories C ON C.event_id = R.event_id

WHERE 1=1
  AND V.field_id IN(14,26,27,15)
  AND R.published <> 2 /*Including this line omits Cancelled Invoices */
  AND R.published IS NOT NULL
  AND (R.published = 1 OR R.payment_method = "os_offline") 
  AND (R.register_date >= CURDATE() - INTERVAL 14 DAY)

GROUP BY E.event_date, E.title, R.id, R.first_name, R.last_name, R.email,R.register_date, R.amount, R.comment

ORDER BY R.register_date DESC, R.transaction_id

这会产生这样的输出

我正在使用以下查询尝试将具有共同 transaction_ID 的行(最后一张图片中的第 2 行和第 3 行)组合在一起 - 我在要聚合的列上添加 group_concat 并将 Group By 更改为transaction_id

SELECT
  R.id as ID,
  E.event_date as ServiceDate,
  E.event_date - INTERVAL 1 DAY as DueDate,
  Concat('Ad-Hoc Booking:',E.title) as ItemProductService,
  Concat(R.first_name, ' ',R.last_name) as Customer,
  R.first_name as FirstName,
  R.last_name as LastName,
  R.email,
  R.register_date as InvoiceDate,
  R.amount as ItemAmount,
  R.comment,
  R.number_registrants as ItemQuantity,
  R.transaction_id as InvoiceNo,
  R.published as Status,
  
  
  Group_ConCat( E.event_date) AS SERVICEDATE,
Group_ConCat( Concat('Ad-Hoc Booking:',E.title)) AS DESCRIPTION,
Group_ConCat( R.number_registrants) AS QUANTITY,
Group_ConCat( FORMAT(R.amount / R.number_registrants,2)) AS RATE2,
Group_ConCat( R.amount) AS AMOUNT,
Group_ConCat( C.category_id) as CLASS,

  Concat(Group_Concat(V.field_value SEPARATOR ', '),'. ',R.comment) as Memo

FROM dcea4_eb_events E
LEFT JOIN dcea4_eb_registrants R  ON R.event_id = E.id
LEFT JOIN dcea4_eb_field_values V ON V.registrant_id = R.id
LEFT JOIN dcea4_eb_event_categories C ON C.event_id = R.event_id

WHERE 1=1
  AND V.field_id IN(14,26,27,15)
  AND R.published <> 2 /*Including this line omits Cancelled Invoices */
  AND R.published IS NOT NULL
  AND (R.published = 1 OR R.payment_method = "os_offline") 
  AND (R.register_date >= CURDATE() - INTERVAL 14 DAY)

GROUP BY R.transaction_id

ORDER BY R.register_date DESC, R.transaction_id

但这会产生这个输出

它似乎在增加行数。第一行的 Quantity 列应该是 1 ,第二行应该是 2,1 。

我尝试过将 Group_Concat 与 DISTINCT 一起使用,但这不起作用,因为连接的值通常是相同的(例如,预订的两个事件的价格都相同)并且查询只返回一个值,例如10 而不是 10, 10。后者是我需要的。

我猜问题出在表的连接方式上,但我正在努力弄清楚如何获得我需要的东西。

最受赞赏的正确方向的指针。

【问题讨论】:

  • 考虑处理应用代码中数据显示的问题
  • 而V和R都是INNER JOIN
  • @Stawberry - 感谢您对所需连接类型的指导。关于应用层中的数据表示,我同意你的观点——但在这种情况下,我确实需要让这个查询正常工作。我已经看到有类似问题的帖子,并且在进行连接之前解决方案指向聚合,但答案并没有为我微薄的 SQL 能力提供足够的解释来解释。因此,我们将不胜感激地收到任何进一步的指导

标签: mysql join group-concat


【解决方案1】:

你似乎决心要走在我看来是错误的方向,所以这里轻轻推下那座山……

考虑以下...

CREATE TABLE users
(user_id SERIAL PRIMARY KEY
,username VARCHAR(12) UNIQUE
);

INSERT INTO users VALUES
(101,'John'),(102,'Paul'),(103,'George'),(104,'Ringo');

DROP TABLE IF EXISTS sales;

CREATE TABLE sales
(sale_id SERIAL PRIMARY KEY
,purchaser_id INT NOT NULL
,item_code CHAR(1) NOT NULL
,quantity INT NOT NULL
);


INSERT INTO sales VALUES
( 1,101,'A',1),
( 2,103,'A',2),
( 3,103,'A',3),
( 4,104,'A',1),
( 5,104,'A',2),
( 6,104,'A',3),
( 7,103,'B',2),
( 8,103,'B',2),
( 9,104,'B',3),
(10,103,'B',2),
(11,104,'B',2),
(12,104,'B',1);

SELECT u.* 
     , x.sale_ids
     , x.item_codes
     , x.quantities
  FROM users u 
  LEFT
  JOIN 
     ( SELECT purchaser_id
            , GROUP_CONCAT(sale_id ORDER BY sale_id) sale_ids
            , GROUP_CONCAT(item_code ORDER BY sale_id) item_codes
            , GROUP_CONCAT(quantity ORDER BY sale_id) quantities
         FROM sales
        GROUP 
           BY purchaser_id
     ) x
    ON x.purchaser_id = u.user_id;
    
    +---------+----------+---------------+-------------+-------------+
    | user_id | username | sale_ids      | item_codes  | quantities  |
    +---------+----------+---------------+-------------+-------------+
    |     101 | John     | 1             | A           | 1           |
    |     102 | Paul     | NULL          | NULL        | NULL        |
    |     103 | George   | 2,3,7,8,10    | A,A,B,B,B   | 2,3,2,2,2   |
    |     104 | Ringo    | 4,5,6,9,11,12 | A,A,A,B,B,B | 1,2,3,3,2,1 |
    +---------+----------+---------------+-------------+-------------+

【讨论】:

  • 谢谢,我会试试这个方法。
猜你喜欢
  • 2012-11-22
  • 2016-09-22
  • 2020-02-05
  • 2017-08-08
  • 2016-02-10
  • 1970-01-01
  • 1970-01-01
  • 2012-09-10
  • 1970-01-01
相关资源
最近更新 更多