Oracle SQL Query未显示所有记录

时间:2014-04-17 17:25:07

标签: sql oracle

我有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个好。

有人可以指出我正确的方向吗?

2 个答案:

答案 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;