Reputation: 83
I have data from tests with two lists of parts, called in and out. I need to select SUM of test values for each part after the last test where the part went in but didn't come out.
IN LIST OUT LIST TEST
+--------+-----------+ +--------+------------+ +------+-------+
| testid | in_partid | | testid | out_partid | | test | value |
+--------+-----------+ +--------+------------+ +------+-------+
| 1 | 10 | | 1 | 10 | | 1 | 1 |
| 1 | 20 | | 1 | 20 | | 2 | 10 |
| 2 | 10 | | 2 | 10 | | 3 | 100 |
| 2 | 20 | | | | | | |
| 3 | 10 | | 3 | 10 | | | |
| 3 | 20 | | 3 | 20 | | | |
+--------+-----------+ +--------+------------+ +------+-------+
SUM is pretty straightforward, but can I limit it to those rows where testid is greater than testid for the last inspection where part went in but not out?
In this example, part 10 should SUM all three test values, because it's included in all lists, but part 20 should only return value for test 3, as in test 2 it was not included in both in and out lists.
partid sum(value)
10 111
20 100
Can I do with with mysql, or do I need to include php in the mix?
Upvotes: 0
Views: 350
Reputation: 6106
I think your sample output is incorrect from your logic. I think partid 20 should return 101 as it is present in both lists for both tests 1 and 3. Assuming I'm right in that, this query should return the desired results
SELECT in_partid,SUM(value)
FROM (
SELECT DISTINCT in_partid,inl.testid
FROM in_list inl
INNER JOIN out_list outl ON in_partid=out_partid AND inl.testid=outl.testid
) as tests_passed
INNER JOIN tests ON tests_passed.testid=test
GROUP BY in_partid
EDIT: based on OP's comment my assumption above was wrong and was actually a requirement. Accordingly here is a query that I think fulfils the requirements:
SELECT tests_passed.in_partid,SUM(value)
FROM (
SELECT DISTINCT inl.in_partid,IFNULL(last_failed_test,0) as last_failed_test
FROM in_list inl LEFT JOIN (
SELECT in_partid,MAX(inl.testid) as last_failed_test
FROM in_list inl
LEFT JOIN out_list outl ON in_partid=out_partid AND inl.testid=outl.testid
WHERE outl.testid IS NULL
GROUP BY in_partid
) AS last_passed
ON inl.in_partid=last_passed.in_partid
) as tests_passed
INNER JOIN tests ON tests_passed.last_failed_test<test
GROUP BY tests_passed.in_partid
This returns the sample results given above for the sample data supplied.
Upvotes: 1