我有3张桌子
生产(序列号,批号#,productCode)600行, 质量(批号#,test1,test2,test3,test4)600行, 有缺陷的(defectID,serial#)323行
批次#链接在生产和质量表之间,而串行#链接在生产和缺陷表之间。
我需要制定一个查询,为600个批次#s中的每一个分配一个状态。
需要满足的条件是:
在缺陷表中包含多个序列的每个批次都需要标记为差。如果它有一个或更少,批次质量是好的。
这是我到目前为止所做的:
SELECT p.batch_NO, p.PRODUCT_CODE, q.test_1, q.test_2, q.test_3, q.test_4,
CASE WHEN count(*) <= 1 THEN 'Good'
ELSE 'Poor'
END AS "Batch Quality"
FROM DEFECTIVE d, production p, quality q
WHERE q.BATCH_NO = p.BATCH_NO
And d.serial_NO = p.serial_NO
GROUP BY p.batch_NO, p.PRODUCT_CODE, q.test_1, q.test_2, q.test_3, q.test_4
order by p.batch_NO;
问题是我只获得249行而不是600行。 我应该得到600条记录,其中61个差,539个好。
有人可以指出我正确的方向吗?
答案 0 :(得分:1)
问题是生产表的左/右外连接.. 尝试运行
SELECT p.batch_NO, p.PRODUCT_CODE, q.test_1, q.test_2, q.test_3, q.test_4,
CASE WHEN count(distinct d.serial_NO) <= 1 THEN 'Good'
ELSE 'Poor'
END AS "Batch Quality"
FROM DEFECTIVE d, production p, quality q
WHERE q.BATCH_NO(+) = p.BATCH_NO
And d.serial_NO(+) = p.serial_NO
GROUP BY p.batch_NO, p.PRODUCT_CODE, q.test_1, q.test_2, q.test_3, q.test_4
order by p.batch_NO;
或使用右边的外部连接(在这种情况下)用于没有缺陷且没有质量检查的产品......
(我总是混淆(+)的右侧,你应该正式使用“左外连接”和“右外连接”,而不仅仅是测试)
仅供参考: http://docs.oracle.com/cd/B28359_01/server.111/b28286/queries006.htm#SQLRF52335
答案 1 :(得分:0)
由于您在生产和缺陷表之间进行内部联接,因此只返回序列号有缺陷的批次。
另外,如果缺陷表中可能存在重复的序列号,并且您只想计算不同的序列号,或者如果生产和质量之间存在一对多的关系,那么您需要计算明显有缺陷的序列#而不是count(*)
。您的示例中的Count(*)
永远不会返回0,因为生产表和质量表之间至少有一行,即使有0个有缺陷的记录。
我一般更喜欢使用INNER / LEFT / RIGHT连接sytax与TABLE1,TABLE2格式和外部连接的(+),因为我更容易阅读。这是一个应该有效的版本:
SELECT p.batch_NO, p.PRODUCT_CODE, q.test_1, q.test_2, q.test_3, q.test_4,
CASE
WHEN COUNT(DISTINCT d.serial_NO) <= 1
THEN 'Good'
ELSE 'Poor'
END AS "Batch Quality"
--additional column to help check your output
, COUNT(DISTINCT d.serial_NO) as DefectiveSerialNoCount
FROM production p
LEFT JOIN quality q ON q.BATCH_NO = p.BATCH_NO
LEFT JOIN DEFECTIVE d ON d.serial_NO = p.serial_NO
GROUP BY p.batch_NO, p.PRODUCT_CODE, q.test_1, q.test_2, q.test_3, q.test_4
ORDER BY p.batch_NO;