MySQL 中的 Pivot - 根据日期时间列显示第一个和最后一个值

     2023-02-24     197

关键词:

【中文标题】MySQL 中的 Pivot - 根据日期时间列显示第一个和最后一个值【英文标题】:Pivot in MySQL - Show first and last values depending on datetime-column 【发布时间】:2015-05-13 03:56:47 【问题描述】:

经过数小时的研究和尝试,我终于在 *** 上注册了,它通过阅读帮助了我多年。非常感谢您提供这次学习机会!我现在希望就我无法解决的 MySQL 问题寻求帮助。我被卡住了。

来源:我有一张客户订单表。

输出:我想要按电子邮件地址分组的订单,对于每个电子邮件地址,都应该有总营业额的总和,订单计数以及创建的第一个订单和最后一个订单的行创建的。 到这里为止还好,可以通过分组和 min() 和 max() 函数来完成。 我卡住的地方:我想要第一个和最后一个订单的 IP 地址,第一个名称第一个和最后一个订单等等(请参阅下面的所需输出)。

我尝试和研究的内容: Groupwise max,子选择,子选择内部有一个顺序,外部有一个组,几个连接变体。

这是一个带有随机数据的 SQLfiddle 和一个我构建的 sql 查询。它的工作方式是: http://sqlfiddle.com/#!9/0272b/6

作为 SQLfiddle 中 SQL 的替代方法,我尝试了这个,它适用于一个电子邮件地址:

SELECT
    lastentry.entity_id,
    lastentry.customer_email,
    firstentry.created_at AS FirstOrder,
    lastentry.created_at  AS LastOrder,
    COUNT(lastentry.entity_id) AS TotalOrders,
    SUM(lastentry.grand_total) AS TotalTurnover,
    firstentry.entity_id,
    firstentry.remote_ip AS FirstIP,
    lastentry.remote_ip  AS LastIP
FROM
    orders lastentry
LEFT OUTER JOIN
    (
        SELECT
            co1.entity_id,
            co1.customer_email,
            co1.remote_ip,
            co1.created_at
        FROM
            orders AS co1,
            (
                SELECT
                    customer_email,
                    remote_ip,
                    MIN(created_at) AS maxpop
                FROM
                    orders
                GROUP BY
                    customer_email) AS co2
        WHERE
            co2.customer_email = co1.customer_email
        AND co1.created_at = co2.maxpop ) AS firstentry
ON
    (
        lastentry.customer_email = firstentry.customer_email )
ORDER BY
    lastentry.created_at DESC,
    firstentry.created_at ASC
LIMIT 1

我也尝试在 where 语句中使用子选择进行子选择或加入,但没有运气:

created_at = (SELECT MAX(t2.created_at)
    FROM orders t2
    WHERE customer_email= t1.customer_email
)

我实际想要的输出如下所示:

| customer_email           | FirstOrder          | LastOrder           | TotalOrders | TotalTurnover | FirstIP       | LastIP         | FirstName | LastName |
|--------------------------|---------------------|---------------------|-------------|---------------|---------------|----------------|-----------|----------|
| darmstrong3@skype.com    | 2014-11-06 16:38:31 | 2014-11-15 11:14:42 | 2           | 116,09        | 103.132.17.9  | 153.241.73.137 | David     | David    |
| fthompson0@moonfruit.com | 2014-08-19 06:26:26 | (null)              | 1           | 1,1           | 87.217.157.91 | (null)         | Frank     | (null)   |
| jrice2@icq.com           | 2014-06-01 09:59:10 | (null)              | 1           | 95,76         | 117.4.9.206   | (null)         | Joshua    | (null)   |
| kphillips8@oracle.com    | 2015-01-30 22:49:56 | (null)              | 1           | 57,12         | 220.77.70.87  | (null)         | Kevin     | (null)   |
| lcruz5@techcrunch.com    | 2014-10-27 01:02:46 | (null)              | 1           | 90,45         | 122.38.175.17 | (null)         | Larry     | (null)   |
| scarpenter1@salon.com    | 2012-11-05 07:56:38 | 2014-06-09 21:57:20 | 3           | 163,58        | 220.75.17.164 | 203.81.207.35  | Steven    | Lousie   |

感谢任何帮助!


我问自己的问题:

这可以在 MySQL 中解决吗?在 Excel 中,我可以简单地构建一个数据透视表。 如果不是,我可以通过使用存储过程来解决它,如果订单不超过一个,则遍历所有记录并跳过字段?

【问题讨论】:

【参考方案1】:

我建议使用substring_index()/group_concat() 技巧。它看起来像这样:

SELECT o.entity_id, o.customer_email,
       min(created_at) AS FirstOrder, max(created_at)  AS LastOrder,
       count(*) AS TotalOrders, sum(o.grand_total) AS TotalTurnover,
       substring_index(group_concat(remote_ip order by created at), ',', 1) as first_ip,
       substring_index(group_concat(remote_ip order by created at desc), ',', 1) as last_ip
FROM orders o
GROUP BY o.entity_id, o.customer_email;

这应该适用于合理的数据。 group_concat() 的中间结果的长度有一个可配置的限制。

【讨论】:

解决这个问题的方法很有趣,谢谢你的提示,戈登!我会玩弄它以进一步了解这个技巧!【参考方案2】:

您还可以使用子查询来查找第一个和最后一个订单的行值。这假设第一个和最后一个订单是根据 entity_id。

SELECT 
   customer_email, 
   COUNT(*) AS total_orders, 
   SUM(grand_total) AS total_turnover,
   (SELECT created_at FROM orders WHERE 
       entity_id = MIN(t.entity_id)) AS first_created_at,
   (SELECT created_at FROM orders WHERE 
       entity_id = MAX(t.entity_id)) AS last_created_at,
   (SELECT remote_ip FROM orders WHERE 
       entity_id = MIN(t.entity_id)) AS first_remote_ip,
   (SELECT remote_ip FROM orders WHERE 
       entity_id = MAX(t.entity_id)) AS last_remote_ip,
   (SELECT customer_firstname FROM orders WHERE 
       entity_id = MIN(t.entity_id)) AS first_customer_firstname,
   (SELECT customer_firstname FROM orders WHERE 
       entity_id = MAX(t.entity_id)) AS last_customer_firstname
FROM orders AS t
GROUP BY customer_email

【讨论】:

非常感谢!昨天我一直在朝着这个方向努力,但后来因为我无法让它发挥作用而放弃了这个想法。我会进一步检查您的解决方案。再次感谢您!

oracle根据日期组,其他条件根据pivot行转列。使每个日期条件关联的其他数据只有一行。

selectOPER_TIME,MICROPAY,REFUNDfrom(selecttrunc(oper_time)oper_time,class_name,sum(total_fee)total_feefromwx_pay_detailgroupbytrunc(oper_time),class_name)pivot(sum(total_fee)forclass_namein(‘MicroPay‘ 查看详情

mysql使用内部连接根据数据库中的日期范围显示数据

】mysql使用内部连接根据数据库中的日期范围显示数据【英文标题】:mysqldisplaydatabasedondaterangefromdatabaseusinginnerjoin【发布时间】:2019-11-2012:09:46【问题描述】:我有两个表事件和会话,看起来像这样事件表会话表我想根据日期范... 查看详情

如何根据 MySQL 中的最大日期仅选择左表的一条记录?

】如何根据MySQL中的最大日期仅选择左表的一条记录?【英文标题】:HowtoselectonlyonerecordofthelefttablebasedonitsmaxdateinMySQL?【发布时间】:2020-03-2902:44:35【问题描述】:下面是我的数据库结构Useridname1John2Doe3SmittPostiduser_idtext11Hello21Worl... 查看详情

计算 Pivot SQL 中的总天差

】计算PivotSQL中的总天差【英文标题】:CounttotaldaydifferenceinaPivotSQL【发布时间】:2021-11-2517:11:51【问题描述】:我有两个表中的数据,日期为PAL日期和HUB日期。我希望在一个有6列的表格中显示天数差异:Client1day2days3days4days5daysCl... 查看详情

如何根据表日期导出 MySQL 表?

...【问题讨论】:基本上我想按创建日期的顺序导出数据库中的表,这样我就不应该遇到任何外国/主要/或任何其 查看详情

在 Oracle SQL 中按报告日期的 PIVOT 值

...问题描述】:我正在尝试使用pivot来完成以下操作:源表中的数据如下:CompanyCompanyIDProductCodeProductUnitReportingYearValuea1ddgln20197a1ddgln20202b2bbkg2021 查看详情

C#检查MySql数据库中的日期时间值是不是是今天

】C#检查MySql数据库中的日期时间值是不是是今天【英文标题】:C#checkifdatetimevalueinMySqldatabaseistodayC#检查MySql数据库中的日期时间值是否是今天【发布时间】:2016-10-2108:48:05【问题描述】:我目前正在尝试根据用户在日历上单击... 查看详情

从 MySQL 中根据日期选择记录

】从MySQL中根据日期选择记录【英文标题】:SelectingrecordsbasedondatefromMySQL【发布时间】:2014-04-2309:48:33【问题描述】:我的表格中有两列是ID,日期。date是日期时间戳(例如:2014-04-0102:30:00)。我想根据日期(2014-04-01)返回所有记... 查看详情

从 Laravel 中的 Mysql Pivot 表中获取列并返回 JSON 对象

】从Laravel中的MysqlPivot表中获取列并返回JSON对象【英文标题】:GettingcolumnfromaMysqlPivottableinLaravelandreturningaJSONobject【发布时间】:2020-01-0603:05:18【问题描述】:我正在开发一个使用Laravel构建的应用程序,在后端,我在两个表之间... 查看详情

mysql分别获取已有数据date中的年月日

...中有一字段Date,类型为date,已有数据,如何分别获取其中的年、月、日?不是获得当前日期哦!以每24小时作为一份时间(而非自然日),根据用户的配置有两种工作模式:带状模式中,用户仅定义开始日期时,从开始日期(... 查看详情

Mysql,根据日期选择行

】Mysql,根据日期选择行【英文标题】:Mysql,selectrowsaccordingtodate【发布时间】:2012-10-0413:14:33【问题描述】:我想做的事:选择日期=2012-10-14的行,然后显示该行之后的4行。所以从这个列表中2012-10-12column#22012-10-13column#22012-10-14wa... 查看详情

如何根据日期列中的月份从 SQLite 中获取数据

】如何根据日期列中的月份从SQLite中获取数据【英文标题】:HowtoFetchdatafromSQLiteaccordingtoMonthfromaDateColumn【发布时间】:2013-08-1211:46:24【问题描述】:我面临一个简单的问题。我一直使用MSSQL和MySQL,这是我第一次使用SQLite。我想... 查看详情

如何将excel中的日期时间列插入mySQL中的日期时间字段?

】如何将excel中的日期时间列插入mySQL中的日期时间字段?【英文标题】:HowtoinsertadatetimecolumnfromexcelintodatetimefieldinmySQL?【发布时间】:2017-12-3121:38:52【问题描述】:我编写了一个python脚本来将数据从excel电子表格导入mysql数据库... 查看详情

MySQL ORDER BY 根据日期时间查询返回不正确的结果

】MySQLORDERBY根据日期时间查询返回不正确的结果【英文标题】:MySQLORDERBYreturningincorrectresultsbasedondatetimequery【发布时间】:2015-10-1222:01:29【问题描述】:我遇到了一些我不理解的MySQL查询行为我正在运行MySQL5.5.42我有什么我有一... 查看详情

MySQL 翻转表 (pivot)

】MySQL翻转表(pivot)【英文标题】:MySQLfliptable(pivot)【发布时间】:2021-09-1908:40:01【问题描述】:**更新:谢谢大家!SUM成功了。我的查询运行时间不到5秒,而不是我之前的蹩脚解决方案需要8分钟才能得出相同的结果!!**我有一... 查看详情

根据字段名称列选择

...述】:我希望能够合并多个表,以便对用户在我的数据库中的所有表中所做的事情有一个共同的了解。我所有的表都有“终端”和“创建日期”作为公共字段。这样做的最终目标是在不实际使用PIVOT或UNPIVOT的情况下旋转表并将它... 查看详情

FullCalendar - 如何根据逗号分隔的日期从日历上的数据库(mysql)表行显示事件

...:05:42【问题描述】:我正在尝试根据数据库中表的同一行中的日期显示多个事件,以逗号分隔,如图所示:Image 查看详情

MySQL查询根据日期查找最长的值序列

】MySQL查询根据日期查找最长的值序列【英文标题】:MySQLquerytofindthelongestsequenceofvaluebasedondate【发布时间】:2021-06-2015:17:15【问题描述】:我想根据日期列找到给定值的最长序列,例如给定表格:+-------+-------------------+|value|timest... 查看详情