三个表的结构。
预订
CREATE TABLE `booking` (
`bookingID` int(11) NOT NULL AUTO_INCREMENT,
`receipt_no` int(11) NOT NULL,
`client` varchar(32) NOT NULL,
`operator` varchar(32) NOT NULL,
`discount` int(11) NOT NULL,
`total_amount` int(64) NOT NULL,
`amount_paid` int(32) NOT NULL,
`balance` int(32) NOT NULL,
`date` date NOT NULL,
PRIMARY KEY (`bookingID`)
ENGINE=InnoDB AUTO_INCREMENT=209 DEFAULT CHARSET=latin1
JOBTITLE
CREATE TABLE `jobtitle` (
`jobtitleID` int(11) NOT NULL AUTO_INCREMENT,
`jobtitle` varchar(255) NOT NULL,
`quantity` int(11) NOT NULL,
`amount` varchar(255) NOT NULL,
`jobtypeID` int(11) NOT NULL,
`bookingID` int(11) NOT NULL,
PRIMARY KEY (`jobtitleID`)
ENGINE=InnoDB AUTO_INCREMENT=463 DEFAULT CHARSET=latin1
First_graphics_debtors
CREATE TABLE `first_graphics_debtors`
`id` int(11) NOT NULL AUTO_INCREMENT,
`receipt_no` int(11) NOT NULL,
`date_paid` date NOT NULL,
`old_balance` int(32) NOT NULL,
`debtor_amount_paid` int(32) NOT NULL,
`new_balance` int(32) NOT NULL,
PRIMARY KEY (`id`)
ENGINE=InnoDB AUTO_INCREMENT=16 DEFAULT CHARSET=latin1
插入少量数据后
预订
+-----------+------------+----------+----------+----------+--------------+-------------+---------+------------+
| bookingID | receipt_no | client | operator | discount | total_amount | amount_paid | balance | date |
+-----------+------------+----------+----------+----------+--------------+-------------+---------+------------+
| 205 | 156872940 | Osaro | Obi | 10 | 156380 | 135000 | 5742 | 2012-05-15 |
| 206 | 227349168 | Amaka | Stephen | 4 | 73250 | 70320 | 0 | 2012-05-15 |
| 207 | 155732278 | Aghahowa | Ibori | 0 | 116836 | 15000 | 101836 | 2012-05-15 |
| 208 | 753263343 | Chaka | Stephen | 10 | 231290 | 56000 | 152161 | 2012-05-15 |
+-----------+------------+----------+----------+----------+--------------+-------------+---------+------------+
JOBTITLE
+------------+---------------------------+----------+--------+-----------+-----------+
| jobtitleID | jobtitle | quantity | amount | jobtypeID | bookingID |
+------------+---------------------------+----------+--------+-----------+-----------+
| 454 | A1 Full Colour | 10 | 4334 | 1 | 205 |
| 455 | Complementry Card | 20 | 5652 | 2 | 205 |
| 456 | A4 Printout (graphics)B/W | 25 | 2930 | 4 | 206 |
| 457 | Scan | 2 | 4334 | 5 | 207 |
| 458 | A4 Full Colour | 199 | 500 | 3 | 207 |
| 459 | ID Card | 2 | 4334 | 2 | 207 |
| 460 | A3 Full Colour | 10 | 4334 | 3 | 208 |
| 461 | Flex Banner | 20 | 2930 | 2 | 208 |
| 462 | A2 Single Colour | 199 | 650 | 1 | 208 |
+------------+---------------------------+----------+--------+-----------+-----------+
First_graphics_debtors
+----+------------+------------+-------------+--------------------+-------------+
| id | receipt_no | date_paid | old_balance | debtor_amount_paid | new_balance |
+----+------------+------------+-------------+--------------------+-------------+
| 7 | 156872940 | 2012-05-15 | 5742 | 5000 | 742 |
| 8 | 156872940 | 2012-05-15 | 5742 | 5742 | 0 |
| 9 | 753263343 | 2012-05-15 | 152161 | 152161 | 0 |
| 13 | 753263343 | 2012-05-15 | 152161 | 14524 | 137637 |
| 14 | 753263343 | 2012-05-15 | 152161 | 2000 | 150161 |
| 15 | 753263343 | 2012-05-15 | 152161 | 1000 | 151161 |
+----+------------+------------+-------------+--------------------+-------------+
当我运行此查询时:
SELECT `booking`.`receipt_no`, `client`, `operator`, `discount`, `total_amount`,
`amount_paid`, `balance`, `date`, `jobtitle`, `quantity`, `amount`,
`date_paid`, `old_balance`, `debtor_amount_paid`, `new_balance`
FROM (`booking`)
JOIN `jobtitle` ON `jobtitle`.`bookingID` = `booking`.`bookingID`
JOIN `first_graphics_debtors`
ON `first_graphics_debtors`.`receipt_no` = `booking`.`receipt_no`
WHERE `booking`.`receipt_no` = '753263343'
AND `first_graphics_debtors`.`receipt_no` = '753263343'
GROUP BY `jobtitle`.`quantity`
我得到了这个输出:
+------------+--------+----------+----------+--------------+-------------+---------+------------+------------------+----------+--------+------------+-------------+--------------------+-------------+
| receipt_no | client | operator | discount | total_amount | amount_paid | balance | date | jobtitle | quantity | amount | date_paid | old_balance | debtor_amount_paid | new_balance |
+------------+--------+----------+----------+--------------+-------------+---------+------------+------------------+----------+--------+------------+-------------+--------------------+-------------+
| 753263343 | Chaka | Stephen | 10 | 231290 | 56000 | 152161 | 2012-05-15 | A3 Full Colour | 10 | 4334 | 2012-05-15 | 152161 | 152161 | 0 |
| 753263343 | Chaka | Stephen | 10 | 231290 | 56000 | 152161 | 2012-05-15 | Flex Banner | 20 | 2930 | 2012-05-15 | 152161 | 152161 | 0 |
| 753263343 | Chaka | Stephen | 10 | 231290 | 56000 | 152161 | 2012-05-15 | A2 Single Colour | 199 | 650 | 2012-05-15 | 152161 | 152161 | 0 |
+------------+--------+----------+----------+--------------+-------------+---------+------------+------------------+----------+--------+------------+-------------+--------------------+-------------+
以下列的数据重复三次,而不是从与receipt_no相关的四行中获取数据
date_paid, old_balance, debtor_amount_paid, new_balance
预期结果
+------------+--------+----------+----------+--------------+-------------+---------+------------+------------------+----------+--------+------------+-------------+--------------------+-------------+
| receipt_no | client | operator | discount | total_amount | amount_paid | balance | date | jobtitle | quantity | amount | date_paid | old_balance | debtor_amount_paid | new_balance |
+------------+--------+----------+----------+--------------+-------------+---------+------------+------------------+----------+--------+------------+-------------+--------------------+-------------+
| 753263343 | Chaka | Stephen | 10 | 231290 | 56000 | 152161 | 2012-05-15 | A3 Full Colour | 10 | 4334 | 2012-05-15 | 152161 | 152161 | 0 |
| 753263343 | Chaka | Stephen | 10 | 231290 | 56000 | 152161 | 2012-05-15 | Flex Banner | 20 | 2930 | 2012-05-15 | 152161 | 14524 | 137637 |
| 753263343 | Chaka | Stephen | 10 | 231290 | 56000 | 152161 | 2012-05-15 | A2 Single Colour | 199 | 650 | 2012-05-15 | 152161 | 2000 | 150161 |
+------------+--------+----------+----------+--------------+-------------+---------+------------+------------------+----------+--------+------------+-------------+--------------------+-------------+
尽管如此,预期的输出尚未完成,但也许您可以从debtor_amount_paid
和new_balance
上的数据中获取图片
答案 0 :(得分:1)
我很确定你的问题是因为你的GROUP BY
条款。不确定你使用它的目的是什么,但尝试没有它。如果您获得重复的行,请尝试使用SELECT DISTINCT
。如果您的目标是根据该列订购结果,请使用ORDER BY
。
此外,在receipt_no
子句中指定WHERE
两次是多余的。这两个表已经被该列连接,因此您需要在一个表中对其进行过滤。并且除了一些特殊的异常(例如列名中的空格或逗号)或者与保留字命名相同的列(也可能是其他几个)之外,反引号并不是必需的。您的唯一一列看起来需要反引号是date
列,但即使在该列上排除它们,您仍应该没问题。我发现到处都是反复使得查询更长,更难阅读。他们不会因为在那里而伤害任何东西,所以如果这是你的偏好,你可以留下他们,但就个人而言,我不是粉丝。
我用上面提到的修改重写了你的查询,而且我给表别名以进一步缩短它。这不会提高性能或任何东西,只是让它更容易阅读IMO:
SELECT DISTINCT
b.receipt_no, client, operator, discount, total_amount,
amount_paid, balance, `date`, jobtitle, quantity,
amount, date_paid, old_balance, debtor_amount_paid, new_balance
FROM
booking b
INNER JOIN jobtitle jt ON jt.bookingID = b.bookingID
INNER JOIN first_graphics_debtors fgd ON fgd.receipt_no = b.receipt_no
WHERE
b.receipt_no = '753263343'
ORDER BY
jt.quantity
答案 1 :(得分:1)
您可能希望使用FULL JOIN来对齐这些连接的行,但由于MySQL上没有FULL JOIN,您必须与UNION竞争:
压缩代码以避免滚动条:
select bx.*, null as sepy, booking_particulars.*
from booking bx
join (
select same_n,
max(Receipt_No) as Receipt_No, max(Quantity) as Quantity,
max(Amount) as Amount,
null as sepx, -- separator
max(Date_Paid) as Date_Paid, max(Old_Balance) as Old_Balance,
max(Debtor_Amount_Paid) as Debtor_Amount_Paid,
max(New_Balance) as New_Balance
from (
select *
from (
select b.Receipt_No, j.Quantity, j.Amount,
null as Date_Paid, null as Old_Balance, null as Debtor_Amount_Paid,
null as New_Balance, @j_rn := @j_rn + 1 as same_n
from (booking b, (select @j_rn := 0) as vars)
join jobtitle j ON j.bookingID = b.bookingID
where b.receipt_no = '753263343'
order by j.JobTitleId
) as jx
union all
select * from (
select f.Receipt_No, null as Quantity, null as Amount,
f.Date_Paid, f.Old_Balance, f.Debtor_Amount_Paid,
f.New_Balance, @f_rn := @f_rn + 1 as same_n
from (first_graphics_debtors f, (select @f_rn := 0) as vars)
where f.receipt_no = '753263343'
order by f.id
) as fx
) as z
group by same_n order by same_n
) as booking_particulars on booking_particulars.receipt_no = bx.receipt_no
输出:
| BOOKINGID | RECEIPT_NO | CLIENT | OPERATOR | DISCOUNT | TOTAL_AMOUNT | AMOUNT_PAID | BALANCE | DATE | SEPY | SAME_N | QUANTITY | AMOUNT | SEPX | DATE_PAID | OLD_BALANCE | DEBTOR_AMOUNT_PAID | NEW_BALANCE |
|-----------|------------|--------|----------|----------|--------------|-------------|---------|----------------------------|--------|--------|----------|--------|--------|----------------------------|-------------|--------------------|-------------|
| 208 | 753263343 | Chaka | Stephen | 10 | 231290 | 56000 | 152161 | May, 15 2012 08:00:00-0700 | (null) | 1 | 10 | 4334 | (null) | May, 15 2012 08:00:00-0700 | 152161 | 152161 | 0 |
| 208 | 753263343 | Chaka | Stephen | 10 | 231290 | 56000 | 152161 | May, 15 2012 08:00:00-0700 | (null) | 2 | 20 | 2930 | (null) | May, 15 2012 08:00:00-0700 | 152161 | 14524 | 137637 |
| 208 | 753263343 | Chaka | Stephen | 10 | 231290 | 56000 | 152161 | May, 15 2012 08:00:00-0700 | (null) | 3 | 199 | 650 | (null) | May, 15 2012 08:00:00-0700 | 152161 | 2000 | 150161 |
| 208 | 753263343 | Chaka | Stephen | 10 | 231290 | 56000 | 152161 | May, 15 2012 08:00:00-0700 | (null) | 4 | (null) | (null) | (null) | May, 15 2012 08:00:00-0700 | 152161 | 1000 | 151161 |
在此处进行实时测试和查询进展:http://www.sqlfiddle.com/#!2/d8d3b/45
答案 2 :(得分:0)
我完全同意Travesty3关于表别名和反引号的内容。
我认为,您的问题是,您正试图将“应该”和“应该”的内容结合起来。是两个单独的查询到一个。对于任何给定的预订,您可以拥有任意数量的职位条目,并且完全独立于职位信息,您可以拥有任意数量的First Graphics Debtors条目。在样品收据753263343的样本数据中,您有一个预订,三个职称条目和4个第一图形债务人条目。
默认情况下(没有GROUP BY子句),您将得到12个条目,对应于三组行的交叉积(1 x 3 x 4)。
MySQL中的GROUP BY与大多数其他DBMS不同;标准SQL不允许您省略GROUP BY子句中的非聚合列(并且所有列都是非聚合的)。
我认为您之后的输出结果集类似于(使用FGD作为First Graphics Debtors的缩写):
+-------------------+---------------------+---------------+
| Data from Booking | Data from Job Title | Data from FGD |
+-------------------+---------------------+---------------+
| Booking ID 208... | Job Title ID 460... | FGD ID 9 |
| Booking ID 208... | Job Title ID 461... | FGD ID 13 |
| Booking ID 208... | Job Title ID 462... | FGD ID 14 |
| Booking ID 208... | ...?????????????... | FGD ID 15 |
+-------------------+---------------------+---------------+
问号的最合理的值集可能是一组NULL。
但是,您可能会更好,使用两个单独的查询,一个用于获取职位信息,一个用于获取FGD信息(两个中只有一个需要返回预订信息)。但是,您必须在应用程序代码中进行一些演示工作(这是应该进行演示工作的地方,但这是一个不同的讨论)。
因此,对于胆小的人,我建议使用两个查询。对于勇敢者,请继续阅读...
更新: TDQD - 包括测试的材料有点错误。
首先,让我说明一下:如果这是你所追求的,那么这是相对艰苦的工作,尽管可以做到。其次,它在DBMS中使用OLAP函数更简单。使用MySQL(以及其他一些DBMS),您可以使用临时表来保存中间结果。
您在预订ID上加入预订和职位。您在收据编号上加入Booking和FGD。假设我们创建了两个中间结果集:
SequencedJobTitles(Booking ID, Job_Seq_No)
SequencedReceipts(Receipt No, Rec_Seq_No)
其中第一个作业序列号从每个预订ID的1..N开始,每个收据号的收据序列号从1..M开始。
现在我们可以写:
SELECT B.*, J.*, R.*
FROM Booking AS B
LEFT JOIN (SELECT J1.*, J2.Job_Seq_No
FROM SequencedJobTitles AS J2
JOIN JobTitle AS J1 ON J2.BookingID = J1.BookingID
) AS J
ON B.BookingID = J.BookingID
LEFT JOIN (SELECT R1.*, R2.Rec_Seq_No
FROM SequencedReceipts AS R2
JOIN First_Graphics_Debtors AS R1 ON R1.Receipt_No = R2.Receipt_No
) AS R
WHERE J.Job_Seq_No = R.Rec_Seq_No
AND B.Receipt_No = 753263343
ORDER BY B.BookingID, COALESCE(J2.Job_Seq_No, R2.Rec_Seq_No);
是的,使用*
是懒惰的;我对其进行了优化,以列出生产查询中我想要的列的确切列表。对于调试,它可以确保您查看所有数据,这可能会有所帮助。
如何创建两个中间结果集?
如果没有OLAP功能,您可以使用以下命令生成SequencedJobTitles:
SELECT J1.BookingID, COUNT(*) AS Job_Seq_No
FROM JobTitle AS J1
JOIN JobTitle AS J2
ON J1.BookingID = J2.BookingID
WHERE J1.JobTitleID <= J2.JobTitleID
GROUP BY J1.BookingID;
与SequencedReceipts类似:
SELECT R1.Receipt_No, COUNT(*) AS Rec_Seq_No
FROM First_Graphics_Debtors AS R1
JOIN First_Graphics_Debtors AS R2
ON R1.Receipt_No = R2.Receipt_No
WHERE R1.ID <= R2.ID
GROUP BY R1.Receipt_No;
这些表达式使用非等值连接的自连接,这是非常昂贵的。如果表格很大,您可能希望仅将相关的预订ID或收据号码限制在子查询中。请注意,您可以单独测试这些子查询;这对于TDQD(测试驱动查询设计)来说是一个好主意。
但是,我们可以简单地将这些子查询插入到之前开发的主查询中:
SELECT B.*, J.*, R.*
FROM Booking AS B
LEFT JOIN (SELECT J1.*, J2.Job_Seq_No
FROM (SELECT J1.BookingID, COUNT(*) AS Job_Seq_No
FROM JobTitle AS J1
JOIN JobTitle AS J2
ON J1.BookingID = J2.BookingID
WHERE J1.JobTitleID <= J2.JobTitleID
GROUP BY J1.BookingID
) AS J2
JOIN JobTitle AS J1 ON J2.BookingID = J1.BookingID
) AS J
ON B.BookingID = J.BookingID
LEFT JOIN (SELECT R1.*, R2.Rec_Seq_No
FROM (SELECT R1.Receipt_No, COUNT(*) AS Rec_Seq_No
FROM First_Graphics_Debtors AS R1
JOIN First_Graphics_Debtors AS R2
ON R1.Receipt_No = R2.Receipt_No
WHERE R1.ID <= R2.ID
GROUP BY R1.Receipt_No
) AS R2
JOIN First_Graphics_Debtors AS R1 ON R1.Receipt_No = R2.Receipt_No
) AS R
ON J.Job_Seq_No = R.Rec_Seq_No
WHERE B.Receipt_No = 753263343
ORDER BY B.BookingID, COALESCE(J2.Job_Seq_No, R2.Rec_Seq_No);
警告:未经测试的SQL!
更新:这个警告没有放在那里。无论我怎么努力,我都不相信自己第一次准确地编写复杂的查询。而且我并没有尝试制作我之前展示的轮廓结果(我总是使用两个单独的查询并将数据组合在演示工具方法中),所以我认为错误是不可避免的。 / p>
Real TDQD显示序列查询很接近,但不正确。虽然我将<=
条件更改为>=
条件,但这更具有外观性而非实质性。正确的查询如下:
SELECT J1.BookingID, J1.JobTitleID, COUNT(*) AS Job_Seq_No
FROM JobTitle AS J1
JOIN JobTitle AS J2
ON J1.BookingID = J2.BookingID
WHERE J1.JobTitleID >= J2.JobTitleID
GROUP BY J1.BookingID, J1.JobTitleID;
SELECT R1.Receipt_No, R1.ID, COUNT(*) AS Rec_Seq_No
FROM First_Graphics_Debtors AS R1
JOIN First_Graphics_Debtors AS R2
ON R1.Receipt_No = R2.Receipt_No
WHERE R1.ID >= R2.ID
GROUP BY R1.Receipt_No, R1.ID;
这两个结果可以用相应的表连接起来,但是连接条件与我最初写的不同:
SELECT J4.*, J3.Job_Seq_No
FROM (SELECT J1.BookingID, J1.JobTitleID, COUNT(*) AS Job_Seq_No
FROM JobTitle AS J1
JOIN JobTitle AS J2
ON J1.BookingID = J2.BookingID
WHERE J1.JobTitleID >= J2.JobTitleID
GROUP BY J1.BookingID, J1.JobTitleID
) AS J3
JOIN JobTitle AS J4
ON J3.BookingID = J4.BookingID
AND J3.JobTitleID = J4.JobTitleID
ORDER BY J4.BookingID, J3.Job_Seq_No;
SELECT R4.*, R3.Rec_Seq_No
FROM (SELECT R1.Receipt_No, R1.ID, COUNT(*) AS Rec_Seq_No
FROM First_Graphics_Debtors AS R1
JOIN First_Graphics_Debtors AS R2
ON R1.Receipt_No = R2.Receipt_No
WHERE R1.ID >= R2.ID
GROUP BY R1.Receipt_No, R1.ID
) AS R3
JOIN First_Graphics_Debtors AS R4
ON R3.Receipt_No = R4.Receipt_No
AND R3.ID = R4.ID
ORDER BY R4.Receipt_No, R3.Rec_Seq_No;
然后你可以运行这个查询:
SELECT B.*, J.*, R.*
FROM Booking AS B
LEFT JOIN (SELECT J4.*, J3.Job_Seq_No
FROM (SELECT J1.BookingID, J1.JobTitleID, COUNT(*) AS Job_Seq_No
FROM JobTitle AS J1
JOIN JobTitle AS J2
ON J1.BookingID = J2.BookingID
WHERE J1.JobTitleID >= J2.JobTitleID
GROUP BY J1.BookingID, J1.JobTitleID
) AS J3
JOIN JobTitle AS J4
ON J3.BookingID = J4.BookingID
AND J3.JobTitleID = J4.JobTitleID
) AS J
ON B.BookingID = J.BookingID
LEFT JOIN (SELECT R4.*, R3.Rec_Seq_No
FROM (SELECT R1.Receipt_No, R1.ID, COUNT(*) AS Rec_Seq_No
FROM First_Graphics_Debtors AS R1
JOIN First_Graphics_Debtors AS R2
ON R1.Receipt_No = R2.Receipt_No
WHERE R1.ID >= R2.ID
GROUP BY R1.Receipt_No, R1.ID
) AS R3
JOIN First_Graphics_Debtors AS R4
ON R3.Receipt_No = R4.Receipt_No
AND R3.ID = R4.ID
) AS R
ON B.Receipt_No = R.Receipt_No
WHERE B.Receipt_No = 753263343
AND J.Job_Seq_No = R.Rec_Seq_No
ORDER BY B.BookingID, NVL(J.Job_Seq_No, R.Rec_Seq_No);
不幸的是,它只在样本数据上产生三行;它省略了4个收据号码中的最后一个。这就是我做TDQD的原因;当我采取捷径时,我发现存在问题。
最后一个查询的结构需要使用FULL OUTER JOIN(通常)连接J和R子查询,因此它们需要共同的收据号或预订ID。我选择将收据编号添加到JobTitle信息中;将预订ID添加到First Graphics Debtors信息可以正常工作;对称性表明两者兼顾,但这也可能被视为过度杀伤。
SELECT B.Receipt_No, J4.*, J3.Job_Seq_No
FROM (SELECT J1.BookingID, J1.JobTitleID, COUNT(*) AS Job_Seq_No
FROM JobTitle AS J1
JOIN JobTitle AS J2
ON J1.BookingID = J2.BookingID
WHERE J1.JobTitleID >= J2.JobTitleID
GROUP BY J1.BookingID, J1.JobTitleID
) AS J3
JOIN JobTitle AS J4
ON J3.BookingID = J4.BookingID
AND J3.JobTitleID = J4.JobTitleID
JOIN Booking AS B
ON B.BookingID = J4.BookingID
ORDER BY J4.BookingID, J3.Job_Seq_No;
然后,将两个排序列表与FULL OUTER JOIN组合:
SELECT *
FROM (SELECT B.Receipt_No, J4.*, J3.Job_Seq_No
FROM (SELECT J1.BookingID, J1.JobTitleID, COUNT(*) AS Job_Seq_No
FROM JobTitle AS J1
JOIN JobTitle AS J2
ON J1.BookingID = J2.BookingID
WHERE J1.JobTitleID >= J2.JobTitleID
GROUP BY J1.BookingID, J1.JobTitleID
) AS J3
JOIN JobTitle AS J4
ON J3.BookingID = J4.BookingID
AND J3.JobTitleID = J4.JobTitleID
JOIN Booking AS B
ON B.BookingID = J4.BookingID
) AS J
FULL OUTER JOIN
(SELECT R4.*, R3.Rec_Seq_No
FROM (SELECT R1.Receipt_No, R1.ID, COUNT(*) AS Rec_Seq_No
FROM First_Graphics_Debtors AS R1
JOIN First_Graphics_Debtors AS R2
ON R1.Receipt_No = R2.Receipt_No
WHERE R1.ID >= R2.ID
GROUP BY R1.Receipt_No, R1.ID
) AS R3
JOIN First_Graphics_Debtors AS R4
ON R3.Receipt_No = R4.Receipt_No
AND R3.ID = R4.ID
) AS R
ON J.Receipt_No = R.Receipt_No AND J.Job_Seq_No = R.Rec_Seq_No
ORDER BY NVL(J.Receipt_No, R.Receipt_No), NVL(J.Job_Seq_No, R.Rec_Seq_No);
最后将其嵌入到主查询中会给出(一个非常详细的版本)所需的结果:
SELECT B.*, JR.*
FROM Booking AS B
JOIN (SELECT NVL(J.Receipt_No, R.Receipt_No) AS Rec_No,
NVL(J.Job_Seq_No, R.Rec_Seq_No) AS Seq_No,
J.*, R.*
FROM (SELECT B.Receipt_No, J4.*, J3.Job_Seq_No
FROM (SELECT J1.BookingID, J1.JobTitleID, COUNT(*) AS Job_Seq_No
FROM JobTitle AS J1
JOIN JobTitle AS J2
ON J1.BookingID = J2.BookingID
WHERE J1.JobTitleID >= J2.JobTitleID
GROUP BY J1.BookingID, J1.JobTitleID
) AS J3
JOIN JobTitle AS J4
ON J3.BookingID = J4.BookingID
AND J3.JobTitleID = J4.JobTitleID
JOIN Booking AS B
ON B.BookingID = J4.BookingID
) AS J
FULL OUTER JOIN
(SELECT R4.*, R3.Rec_Seq_No
FROM (SELECT R1.Receipt_No, R1.ID, COUNT(*) AS Rec_Seq_No
FROM First_Graphics_Debtors AS R1
JOIN First_Graphics_Debtors AS R2
ON R1.Receipt_No = R2.Receipt_No
WHERE R1.ID >= R2.ID
GROUP BY R1.Receipt_No, R1.ID
) AS R3
JOIN First_Graphics_Debtors AS R4
ON R3.Receipt_No = R4.Receipt_No
AND R3.ID = R4.ID
) AS R
ON J.Receipt_No = R.Receipt_No AND J.Job_Seq_No = R.Rec_Seq_No
) AS JR
ON B.Receipt_No = JR.Rec_No
WHERE B.Receipt_No = 753263343
ORDER BY B.BookingID, Seq_No;
有一个非常有选择性的列列表:
SELECT B.BookingID AS Booking,
B.Receipt_No AS Receipt,
B.Client AS Client,
JR.JobTitleID AS Title
JR.JobTitle AS JobTitle,
JR.Old_Balance AS Old_Balance,
JR.New_Balance AS New_Balance
FROM Booking AS B
...
我从样本数据中获得的结果数据是:
booking receipt client title jobtitle old_balance new_balance
208 753263343 Chaka 460 A3 Full Colour 152161 0
208 753263343 Chaka 461 Flex Banner 152161 137637
208 753263343 Chaka 462 A2 Single Colour 152161 150161
208 753263343 Chaka 152161 151161
唯一剩下的问题是MySQL是否支持FULL OUTER JOIN表示法。如果没有,您可以对此样本数据使用RIGHT OUTER JOIN(作业标题信息中的行数少于FGD信息中的行数。)
更新:这是基于现在已知的错误查询。必须在此处进行类似的更改,以使其按要求运行。
使用OLAP函数,我认为您能够像这样创建排序结果集:
SELECT BookingID,
ROW_NUMBER() OVER (PARTITION BY BookingID ORDER BY JobTitleID) AS Job_Seq_No
FROM JobTitle;
SELECT Receipt_No,
ROW_NUMBER() OVER (PARTITION BY Receipt_No ORDER BY ID) AS Rec_Seq_No
FROM First_Graphics_Debtors;
但是,我对SQL的这一部分信心不足。但是,生成的大查询更简单:
SELECT B.*, J.*, R.*
FROM Booking AS B
LEFT JOIN (SELECT J1.*, J2.Job_Seq_No
FROM (SELECT BookingID,
ROW_NUMBER()
OVER (PARTITION BY BookingID ORDER BY JobTitleID)
AS Job_Seq_No
FROM JobTitle
) AS J2
JOIN JobTitle AS J1 ON J2.BookingID = J1.BookingID
) AS J
ON B.BookingID = J.BookingID
LEFT JOIN (SELECT R1.*, R2.Rec_Seq_No
FROM (SELECT Receipt_No,
ROW_NUMBER() OVER (PARTITION BY Receipt_No ORDER BY ID)
AS Rec_Seq_No
FROM First_Graphics_Debtors
) AS R2
JOIN First_Graphics_Debtors AS R1 ON R1.Receipt_No = R2.Receipt_No
) AS R
WHERE J.Job_Seq_No = R.Rec_Seq_No
AND B.Receipt_No = 753263343
ORDER BY B.BookingID, COALESCE(J2.Job_Seq_No, R2.Rec_Seq_No);
警告:更多未经测试的SQL!