繁体   English   中英

如何自我连接表格并根据通过的条件在一行中显示有限数量的结果

[英]How to self join a table and present a limited number of results, based on a passed criteria, in one row

我正在尝试创建一个作业预订报告,该报告将显示在特定日期创建的所有作业,然后是这些作业上每个项目#的最后三个作业(i-no),并在与作业相同的行中显示数据从特定日期开始。 如果没有以前的作业,则该字段将为null(当前为#NUM !,因为我们在Excel中手动进行此操作)。 如果只有一个先前的作业,则将填充相关字段,其余字段为null,依此类推。..我有一个作业表和jobheader表。 它们都包含非常相似的数据,除了两件事:作业表包含创建日期且不包含item#字段,而作业标题表包含项目编号但不包含创建日期字段。 (我正在努力获取包含所有内容的jobheader表,但是无论如何都必须找到该报告的解决方案。)这是我的表:

show CREATE TABLE job

job CREATE TABLE `job` (
`job-no` varchar(12) DEFAULT NULL,
`job-no2` int(11) DEFAULT NULL,
`std-fix-cost` double DEFAULT NULL,
`std-lab-cost` double DEFAULT NULL,
`std-mat-cost` double DEFAULT NULL,
`std-tot-cost` double DEFAULT NULL,
`std-var-cost` double DEFAULT NULL,
`create-date` date DEFAULT NULL,
) ENGINE=InnoDB DEFAULT CHARSET=utf8    


show CREATE TABLE jobheader 

jobheader   CREATE TABLE `jobheader` (
`sdate` date DEFAULT NULL,
`qty` double DEFAULT NULL,
`std-tot-cost` double DEFAULT NULL,
`std-mat-cost` double DEFAULT NULL,
`std-lab-cost` double DEFAULT NULL,
`std-fix-cost` double DEFAULT NULL,
`std-var-cost` double DEFAULT NULL,
`i-no` varchar(30) DEFAULT NULL,
`job-no2` int(11) DEFAULT NULL,
`job-no` varchar(12) DEFAULT NULL,
) ENGINE=InnoDB DEFAULT CHARSET=utf8

这些表由job-no和job-no2连接。

这是我表中的数据:

job table:  
║ job-no   ║ job-no2 ║ std-fix-cost   ║ std-lab-cost ║ std-mat-cost ║ std-tot-cost ║ std-var-cost ║ create-date ║
║ 786993 ║ 0           ║ 177.2188     ║ 515.1117      ║ 1283.929     ║ 2346.3662   ║ 370.1067   ║ 4/04/2019 ║
║ 787041 ║ 0           ║ 59.5367       ║ 70.8075       ║ 886.2611     ║ 1065.5539   ║ 48.9486     ║ 4/04/2019 ║
║ 787041 ║ 1           ║ 103.475       ║ 123.0637      ║ 1067.8726   ║ 1379.4843   ║ 85.073     ║ 4/04/2019 ║  

jobheader table:  
║sdate║qty║std-tot-cost ║std-mat-cost║std-lab-cost║std-fix-cost║std-var-cost║i-no        ║j2║job-no║  
║NULL ║200║    1297.6372║    942.9434║    140.078 ║    117.781 ║    96.8348 ║NEOIN77886NX║1 ║734701║  
║NULL ║250║    1230.327 ║    918.7153║    123.0637║    103.475 ║    85.073  ║NEOIN77886NX║3 ║762822║  
║NULL ║200║    2346.3662║    1283.929║    515.1117║    177.2188║    370.1067║MEDV25653   ║0 ║786993║  
║NULL ║500║    1065.5539║    886.2611║    70.8075 ║    59.5367 ║    48.9486 ║NEOIN77886NX║0 ║787041║

预期的输出(因为其中包含大量数据,所以会很混乱)。 我还附加了一张图像,以更好地表示我要寻找的内容。 在此处输入图片描述

║job-no║j2║create-date║i-no        ║qty║sdate║std-tot-cost║std-mat-cost║std-lab-cost║std-fix-cost║std-var-cost║job-no║j2║Qty║std-tot-cost║std-mat-cost║std-lab-cost║std-fix-cost║std-var-cost║job-no║j2║Qty║std-tot-cost ║std-mat-cost║std-lab-cost║std-fix-cost║std-var-cost║job-no║j2   ║Qty  ║std-tot-cost║std-mat-cost║std-lab-cost║std-fix-cost║std-var-cost║  
║787041║0 ║4/4/2019   ║NEOIN77886NX║200║     ║    1,349.54║    994.85  ║   
 140.08  ║     117.78 ║96.83   ║762822║3 ║250║ 
   1230.327║    918.7153║    123.0637║    103.475 ║    85.073  ║734701║1 ║200║ 
   1297.6372║    942.9434║    140.078 ║    117.781 ║    96.8348 ║#NUM! ║#NUM!║#NUM!║#NUM!   ║#NUM!   ║#NUM!   ║#NUM!   ║#NUM!   ║  
║786993║0 ║4/4/2019   ║MEDV25653   ║200║     ║    2,346.37║    1,283.93║   
 515.11  ║    177.22  ║    370.11  ║#NUM! ║#NUM!║#NUM!║#NUM!║#NUM!║#NUM!║#NUM!║#NUM!║#NUM!║#NUM!║#NUM! ║#NUM!║#NUM!║#NUM!║#NUM!║#NUM!║#NUM!║#NUM!║#NUM!║#NUM!║#NUM!║#NUM!║#NUM!║#NUM!║

以下是我的查询。 现在消除计算字段,它运行没有错误,对于昨天创建的每个作业,给我的结果太多了。 我将它们写为子查询,以便可以限制结果的数量,但是我似乎无法弄清楚如何将jobh.i-no传递到子查询中,因此不允许我限制结果。 如果我能弄清楚这一点,并对每个子查询都使用LIMIT1,LIMIT1,1和LIMIT 2,1,我认为这将满足我的需求。 关于如何更改查询或如何将Item#传递给子查询的任何建议?

select

job.`job-no`,

job.`job-no2`,

job.`create-date`,

jobh.`i-no`,

jobh.qty,

jobh.`start-date`,

jobh.`std-tot-cost`,

jobh.`std-mat-cost`,

jobh.`std-lab-cost`,

jobh.`std-fix-cost`,

jobh.`std-var-cost`,

tmp.`std-tot-cost` as PreviousJobStdTotCost,

tmp.`std-mat-cost` as PreviousJobStdMatCost,

tmp.`std-lab-cost` as PreviousJobStdLabCost,

tmp.`std-fix-cost` as PreviousJobStdFixCost,

tmp.`std-var-cost` as PreviousJobStdVarCost,

tmp2.`std-tot-cost` as PreviousJob2StdTotCost,

tmp2.`std-mat-cost` as PreviousJob2StdMaCost,

tmp2.`std-lab-cost` as PreviousJob2StdLabCost,

tmp2.`std-fix-cost` as PreviousJob2StdFixCost,

tmp2.`std-var-cost` as PreviousJob2StdVarCost,

tmp3.`std-tot-cost` as PreviousJob3StdTotCost,

tmp3.`std-mat-cost` as PreviousJob3StdMatCost,

tmp3.`std-lab-cost` as PreviousJob3StdLabCost,

tmp3.`std-fix-cost` as PreviousJob3StdFixCost,

tmp3.`std-var-cost` as PreviousJob3StdVarCost

from asi.job as job

left join asi.jobheader  as jobh on job.`job-no`=jobh.`job-no` and job.`job-no2`=jobh.`job-no2`

left join (select jobh1.`i-no`, jobh1.`job-no`, jobh1.`std-tot-cost`, jobh1.`std-mat-cost`, jobh1.`std-lab-cost`, jobh1.`std-fix-cost`, jobh1.`std-var-cost` from asi.jobheader as jobh1 order by jobh1.`job-no` desc) tmp on tmp.`i-no`=jobh.`i-no` and tmp.`job-no`not equal to jobh.`job-no`

left join (select jobh2.`i-no`, jobh2.`job-no`, jobh2.`std-tot-cost`, jobh2.`std-mat-cost`, jobh2.`std-lab-cost`, jobh2.`std-fix-cost`, jobh2.`std-var-cost` from asi.jobheader as jobh2 order by jobh2.`job-no` desc ) tmp2 on tmp2.`i-no`=tmp.`i-no` and tmp2.`job-no` not equal to tmp.`job-no`

left join (select jobh3.`i-no`, jobh3.`job-no`, jobh3.`std-tot-cost`, jobh3.`std-mat-cost`, jobh3.`std-lab-cost`, jobh3.`std-fix-cost`, jobh3.`std-var-cost` from asi.jobheader as jobh3 order by jobh3.`job-no` desc) tmp3 on tmp3.`i-no`=tmp2.`i-no` and tmp3.`job-no` not equal to tmp2.`job-no`

where asi.job.`create-date`="2019-04-04" and asi.job.`job-no` is not null and asi.job.`job-no`""

好的,我认为这可能有效,但是我并不乐观。 我绝对怀疑它的执行速度会很快,但这是某件事。

select
job.`job-no`,
job.`job-no2`,
job.`create-date`,
jobh.`i-no`,
jobh.qty,
jobh.`start-date`,
jobh.`std-tot-cost`, jobh.`std-mat-cost`, jobh.`std-lab-cost`, jobh.`std-fix-cost`, jobh.`std-var-cost`,
tmp.`std-tot-cost` as PreviousJobStdTotCost, tmp.`std-mat-cost` as PreviousJobStdMatCost, tmp.`std-lab-cost` as PreviousJobStdLabCost, tmp.`std-fix-cost` as PreviousJobStdFixCost, tmp.`std-var-cost` as PreviousJobStdVarCost,
tmp2.`std-tot-cost` as PreviousJob2StdTotCost, tmp2.`std-mat-cost` as PreviousJob2StdMaCost, tmp2.`std-lab-cost` as PreviousJob2StdLabCost, tmp2.`std-fix-cost` as PreviousJob2StdFixCost, tmp2.`std-var-cost` as PreviousJob2StdVarCost,
tmp3.`std-tot-cost` as PreviousJob3StdTotCost, tmp3.`std-mat-cost` as PreviousJob3StdMatCost, tmp3.`std-lab-cost` as PreviousJob3StdLabCost,
tmp3.`std-fix-cost` as PreviousJob3StdFixCost, tmp3.`std-var-cost` as PreviousJob3StdVarCost
from asi.job as job
left join asi.jobheader as jobh on job.`job-no`=jobh.`job-no` and job.`job-no2`=jobh.`job-no2`
left join (
    select jobh1.`std-tot-cost`, jobh1.`std-mat-cost`, jobh1.`std-lab-cost`, jobh1.`std-fix-cost`, jobh1.`std-var-cost` 
    from asi.jobheader as jobh1 
    where jobh1.`i-no`=jobh.`i-no` and jobh1.`job-no` < jobh.`job-no`
    order by jobh1.`job-no` desc
    limit 1
) tmp on 1=1
left join (
    select jobh2.`std-tot-cost`, jobh2.`std-mat-cost`, jobh2.`std-lab-cost`, jobh2.`std-fix-cost`, jobh2.`std-var-cost` 
    from asi.jobheader as jobh2 
    where jobh2.`i-no`=tmp.`i-no` and jobh2.`job-no` < tmp.`job-no`
    order by jobh2.`job-no` desc 
    limit 1
) tmp2 on 1=1
left join (
    select jobh3.`std-tot-cost`, jobh3.`std-mat-cost`, jobh3.`std-lab-cost`, jobh3.`std-fix-cost`, jobh3.`std-var-cost` 
    from asi.jobheader as jobh3 
    where jobh3.`i-no`=tmp2.`i-no` and jobh3.`job-no` < tmp2.`job-no`
    order by jobh3.`job-no` desc
    limit 1
) tmp3 on 1=1
where asi.job.`create-date`="2019-04-04" 
    and asi.job.`job-no` is not null 
    and asi.job.`job-no`

但是,如果您可以在接收数据的最后进行一些处理,那么这可能是一个更好的解决方案:

select
job.`job-no`,
job.`job-no2`,
job.`create-date`,
jobh.`i-no`,
jobh.qty,
jobh.`start-date`, jobh.`std-tot-cost`, jobh.`std-mat-cost`, jobh.`std-lab-cost`, jobh.`std-fix-cost`, jobh.`std-var-cost`,
prev.`start-date` AS PreviousJobStartDate, prev.`std-tot-cost` as PreviousJobStdTotCost, prev.`std-mat-cost` as PreviousJobStdMatCost, prev.`std-lab-cost` as PreviousJobStdLabCost, prev.`std-fix-cost` as PreviousJobStdFixCost, prev.`std-var-cost` as PreviousJobStdVarCost
from asi.job as job
left join asi.jobheader as jobh on job.`job-no`=jobh.`job-no` and job.`job-no2`=jobh.`job-no2`
left join (
    select jobh1.`start-date`, jobh1.`std-tot-cost`, jobh1.`std-mat-cost`, jobh1.`std-lab-cost`, jobh1.`std-fix-cost`, jobh1.`std-var-cost` 
    from asi.jobheader as jobh1 
    where jobh1.`i-no`=jobh.`i-no` and jobh1.`job-no` < jobh.`job-no`
    order by jobh1.`job-no` desc
    limit 3
) prev on 1=1
where asi.job.`create-date`="2019-04-04" 
    and asi.job.`job-no` is not null 
    and asi.job.`job-no`

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM