簡體   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