Reputation: 610
I get the number of tests taken by a unit :
select
date(START_DATE_TIME), product_id, BATCH_SERIAL_NUMBER, count(*)
from
( select START_DATE_TIME, product_id, uut_serial_number, BATCH_SERIAL_NUMBER
from uut_result
where START_DATE_TIME >= '2016-07-01 00:00:00'
and START_DATE_TIME <= '2016-07-07 23:59:59') as passtbl
group by date(START_DATE_TIME), product_id, batch_serial_number;
I fetch the number of tests a unit passed broken down by day:
select
date(START_DATE_TIME), product_id, BATCH_SERIAL_NUMBER, count(*)
from
( select START_DATE_TIME, product_id, uut_serial_number, BATCH_SERIAL_NUMBER
from uut_result
where START_DATE_TIME >= '2016-07-01 00:00:00'
and START_DATE_TIME <= '2016-07-07 23:59:59'
and uut_status = 'passed' ) as passtbl
group by date(START_DATE_TIME), product_id, batch_serial_number;
what I'm finding is that there are units that don't have any pass records at all, so the second query is returning fewer records than the first. This is breaking post processing. Is there a way to catch the absence of a record and replace it with null or some other dummy value?
Upvotes: 0
Views: 78
Reputation: 2470
My standard answer to everything like this is to use a common table expression and window functions, instead of using group by where you lose the details and have to struggle to recover them.
To get a dummy row you might use a union like this:
;with myCTE (unitId, otherdetail, passed)
as (
select unitDetail, otherdetail, Sum(1) Over (partition by unit) as passed
from sourceTable
)
SELECT unitid, otherDetail, passed
from myCTE
where startDate >= lowerbound and startdate < upperBound
UNION
SELECT unitId, otherdetail, 0 as passed
from sourceTable S
where not exists (select 1 from myCTE where myCTE.unitId = S.unitID
and startDate >= lowerbound and startdate < upperBound)
I think that's a pretty good rough sketch of what you need. Also I would used a half-open interval to compare times On the off chance that the startTime is between 11:59:59 and 0:00 the next day.
You never mentioned what db engine [Duh, it's in the title I was looking for a TAG]. CTE is available on SQL Server and Oracle, but not on MySQL.
For most uses you can substitute a correlated subquery,but you have to repeat yourself. The ';' before WITH is a quirk of SQL Server.
Since you are MySQL, you have to duplicate the CTE as a subquery where it is referenced. Or maybe you have table-valued functions??
Upvotes: 0
Reputation: 37299
select date(START_DATE_TIME),
product_id,
BATCH_SERIAL_NUMBER,
status,
count(*)
from (select *,
case when uut_status = 'passed' then uut_status
else 'other statuses'
end status
from uut_result)
where START_DATE_TIME >= '2016-07-01 00:00:00'
and START_DATE_TIME <= '2016-07-07 23:59:59'
group by date(START_DATE_TIME),
status,
product_id,
batch_serial_number;
Upvotes: 1