MySQL 将行透视为相似记录的列
我有两个表:
- tbl_sms
- tbl_bids
上面两个表包含类似这样的内容:
tbl_sms:
Post_ID | User_ID | SMS_Sent_DT
---------------------------------
123 | 007 | 2010-05-14 10:15:25
123 | 008 | 2010-05-14 10:18:32
123 | 009 | 2010-05-14 10:23:05
123 | 010 | 2010-05-14 10:23:06
tbl_bids:
Post_ID | User_ID | Bid_DT
--------------------------
123 | 010 | 2010-05-14 10:27:25
123 | 008 | 2010-05-14 10:28:32
123 | 009 | 2010-05-14 10:28:47
123 | 007 | 2010-05-14 10:35:06
通过这两个表,我试图实现以下目标:
Post_ID | First_BID_Time | First_BID_SMS_TIME | Second_BID_Time | Second_BID_SMS_Time | Third_BID_Time | Third_BID_SMS_Time
-----------------------------------------------------------------------------------------------------------------------------------
123 | 2010-05-14 10:27:25 | 2010-05-14 10:23:06 | 2010-05-14 10:28:32 | 2010-05-14 10:18:32 | 2010-05-14 10:28:47 | 2010-05-14 10:23:05
我编写的查询是:
SELECT b.post_id,
sms.message_sent_at as notif_sent1,
b.message_sent_at as notif_accepted1,
DATEDIFF(b.message_sent_at, sms.message_sent_at) AS delay1
FROM tbl_bids b
LEFT JOIN tbl_sms_status sms ON (sms.jobid = b.post_id AND b.user_id = sms.userid)
WHERE b.post_id = sms.jobid
ORDER BY b.post_id ASC
这给了我正确的结果,但它们是没有按照我想要的方式旋转。
请有人帮我解决这个问题。我欢迎任何解决方案,无论是完整的冗长查询还是过程。
I have got two tables:
- tbl_sms
- tbl_bids
The above two table holds something like this:
tbl_sms:
Post_ID | User_ID | SMS_Sent_DT
---------------------------------
123 | 007 | 2010-05-14 10:15:25
123 | 008 | 2010-05-14 10:18:32
123 | 009 | 2010-05-14 10:23:05
123 | 010 | 2010-05-14 10:23:06
tbl_bids:
Post_ID | User_ID | Bid_DT
--------------------------
123 | 010 | 2010-05-14 10:27:25
123 | 008 | 2010-05-14 10:28:32
123 | 009 | 2010-05-14 10:28:47
123 | 007 | 2010-05-14 10:35:06
With those two tables I'm trying to achieve the following:
Post_ID | First_BID_Time | First_BID_SMS_TIME | Second_BID_Time | Second_BID_SMS_Time | Third_BID_Time | Third_BID_SMS_Time
-----------------------------------------------------------------------------------------------------------------------------------
123 | 2010-05-14 10:27:25 | 2010-05-14 10:23:06 | 2010-05-14 10:28:32 | 2010-05-14 10:18:32 | 2010-05-14 10:28:47 | 2010-05-14 10:23:05
The query I had written is:
SELECT b.post_id,
sms.message_sent_at as notif_sent1,
b.message_sent_at as notif_accepted1,
DATEDIFF(b.message_sent_at, sms.message_sent_at) AS delay1
FROM tbl_bids b
LEFT JOIN tbl_sms_status sms ON (sms.jobid = b.post_id AND b.user_id = sms.userid)
WHERE b.post_id = sms.jobid
ORDER BY b.post_id ASC
That gives me the correct result but they are not pivoted the way I want it to be.
Can please someone help me out with this one. I welcome any solution be it a full lengthy query or a procedure.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
在 SQL Server 中,使用
ROW_NUMBER()
函数或CROSS APPLY
构造可以轻松实现这一点。在 MySQL 中,这更难。一种解决方案是在 MySQL 中模拟 ROW_NUMBER()使用变量。这样就可以返回按出价时间排名的每个帖子 ID 的出价,并获取 user_ids。从那时起,将 SMS 时间左连接到 post_id/user_id 组合就很容易了。按照链接中的示例,代码将类似于:
然后您将得到如下输出:
您可以将此结果存储在临时表中:
不幸的是,由于 MySQL 限制 您不能在查询中使用对同一个临时表的多个引用,因此您必须拆分该表按排名:
如果记录集非常大,则可以在 Post_ID 上分配(主键)索引以加速旋转查询。
现在您可以旋转这些数据:
OMG Ponies 有一个观点,围绕未旋转的表构建系统更具可扩展性。所以,如果你不需要转向,就不要转向。
In SQL Server this would be easy to accomplish using a
ROW_NUMBER()
function orCROSS APPLY
construct. In MySQL this is harder.One solution is to emulate ROW_NUMBER() in MySQL using variables. This way it is possible to return the bids for each post id ranked on bid time, and get the user_ids. From there on it is an easy matter to LEFT JOIN the SMS time to the post_id/user_id combination. Following the example in the link, the code will be something like:
You'll then have an output like this:
You can store this result in a temporary table:
Unfortunately due to a MySQL limitation you can't use multiple references to the same temporary table in a query, so you'll have to split out this table by ranking:
If the recordset is very large, it pays off to assign a (primary key) index on Post_ID to speed up the pivoting query.
Now you can pivot this data:
OMG Ponies has a point though, it's more scalable to build your system around an unpivoted table. So if you don't need to pivot, don't.