![](/img/trans.png)
[英]MySQL: Self join table offset by one row (equiv to T-SQL CTE with ROW_NUMBER())
[英]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.