【问题标题】:MySQL span multiple rows in fieldsMySQL跨字段中的多行
【发布时间】:2015-06-09 20:44:13
【问题描述】:

我有一张这样的桌子:

Trans Time_In Placard Container Sztp Line Time_Out   
===== ======= ======= ========= ==== ==== ========
IN    10:15   254114  CLHU12345 40DH MAE  10:54   <In transaction
OUT   10:15   254114  MAEU45678 20DR SEA  10:54   <Out Transaction (same placard)
OUT   10:15   254114  TTNU98765 20DR CHI  10:54   <Out Transaction (same placard)

IN    11:23   664524  FSCU13479 40RH SEB  11:55   <In transaction
OUT   11:23   664524  PONU55588 40DR MAB  11:55   <Out Transaction (same placard)

IN    13:01   542234  TLHU77665 40RH MOL  13:23   <In transaction (no out)

OUT   13:36   232212  MLHU22341 20DR CMD  13:49   <Out Transaction (no in)

OUT   14:03   187852  AMFU56041 20DR CMD  14:48   <Out Transaction (no in)
OUT   14:03   187852  CCLU44112 20DR CHN  14:48   <Out Transaction, same placard (no in)

是一张卡车表,这些卡车进入码头以放下一个集装箱,有时会挑选一辆 40 英寸或两辆 20 英寸的卡车出闸。有时卡车司机只是丢了一个容器然后空着走,所以没有 OUT 交易。或者它可能会空了一个完整的容器,所以没有 IN 交易,而只有一两个 OUT,如果他选择一个 40 或两个 20s。每个标语牌的 Time In 和 Time out 都是相同的,所以我可以从任何记录中获取它,所以不用担心。

关键是 Time_In + Placard,因为同一个标语可以多次进出。每次行程的时间戳完全相同。

我需要这样结束:

Trans Time In Placard Cont1     Sztp1  Line1 Cont2     Sztp2 Line2 Cont3     Sztp3 Line3 Time Out
===== ======= ======= ========= =====  ===== ========= ===== ===== ========= ===== ===== ========
IN    10:15   254114  CLHU12345 40DH   MAE   MAEU45678 20DR  SEA   TTNU98765 20DR  CHI   10:54
IN    11:23   664524  FSCU13479 40RH   SEB   PONU55588 40DR  MAB   null      null  null  11:55
IN    13:01   542234  TLHU77665 40RH   MOL   null      null  null  null      null  null  13:23
OUT   13:36   232212  MLHU22341 20DR   CMD   null      null  null  null      null  null  13:49
OUT   14:03   187852  AMFU56041 20DR   CMD   CCLU44112 20DR  CHN   null      null  null  14:48

感谢您的帮助。

更新:只是重写了整个问题,因为它不够清楚。标题也错了,不是多个字段成行,而是相反:多行成字段。很抱歉。

【问题讨论】:

  • 40 & DH 应该是单独的列
  • 不,这是大小/类型,是 4 个字符。
  • 是的,应该是单独的列 - 大小和类型
  • 不,DB上的字段叫sztp。我只是将大小放在列标题中,仅此而已。

标签: mysql sql pivot


【解决方案1】:

我认为 MySQL 存储过程或您的编程语言中的一次性游标操作会更有效。将所有这些复杂的关系合并到一个查询中并不容易实现、审查或维护。

这是另一种使用临时表来构建和保存结果的解决方案,其中 t1 是您的原始数据表,t3 是结果表。

drop table if exists t3;

create temporary table t3 (placecard int, Trans varchar(10), TimeIn varchar(10), ContIn varchar(20), InSize varchar(10), InLine varchar(10), ContOut1 varchar(20),
   ContSize1 Varchar(10), ContLine1 varchar(10), ContOut2 varchar(20), ContSize2 varchar(10), ContLine2 Varchar(10), TimeOut varchar(10) );


insert into t3
(placecard, timein, timeout)
select placecard, min(timein), max(timeout) from t1
group by placecard;


update t3
join t1 
on t3.placecard = t1.placecard  and t3.timein = t1.timein and t1.transaction='IN'
set trans ='IN', contin = t1.Container, InSize = t1.Size, InLine = t1.Line
where t3.placecard>0;

update t3
join t1
on t3.placecard= t1.placecard and t1.transaction='OUT'
set contOut1 = t1.Container , ContLine1 = t1.line , ContSize1 = t1.size
where t3.placecard>0;

update t3
join t1
on t3.placecard= t1.placecard and t1.transaction='OUT' and t3.contOut1 <> t1.Container
set contOut2 = t1.Container , ContLine2 = t1.line , ContSize2 = t1.size
where t3.placecard>0 ;


select * from t3;

您可以将其构建到存储过程中并添加参数以限制范围。

或者您可以将其构建到更新调度表的调度作业中。

【讨论】:

  • 哪个更方便我会使用。该查询将在 BIRT 报告中使用,所以我不确定它在 eclipse 中运行时的行为,如果它必须动态创建和删除表。那就是我正在寻找一个仅查询一次的交易。我可能每隔一小时左右运行一次查询,使用 Pentaho ETL 脚本,然后使用 BIRT 查询连接的表。
  • 您可以使用第三张表而不是临时表。只需在需要时截断并重建。您甚至可以只建立新记录,每小时工作会更快。使它成为一个存储过程,您的代码在查询第三个表之前执行它。没有什么花哨。我会担心它是否能及时给出正确的结果。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-03-14
  • 1970-01-01
  • 2020-09-09
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多