Reputation: 3
I have a table that has the following structure:
id | timestamp | barcode
Timestamp is a datetime
column, and barcode is a full barcode of which I need only the first 9 digits.
I need the count of items for each shift for every day.
Day is the timestamp converted to date.
Shifts are as follows:
And Item Number is just left(barcode, 9)
.
Basically I need a result as:
date | shift | item_number | count
-----------+-------+-------------+------
21.02.2019 | 1 | 298193879 | 32
I managed to group them by date and item number as follows, but it's not returning the desired result.
select
cast([timestamp] as date), left(barcode, 9) as itemnumber, count(*)
from
tablename
group by
cast([timestamp] as date), left(barcode, 9)
Upvotes: 0
Views: 48
Reputation: 1270683
This is basically an aggregation with a bunch of computed columns. Here is one approach:
select cast(timestamp as date) as date,
(case when convert(time, timestamp) >= '06:00:00' and
convert(time, timestamp) < '14:30:00'
then 1
when convert(time, timestamp) >= '14:30:00' and
convert(time, timestamp) < '23:00:00'
then 2
else 3
end) as shift,
left(barcode, 9) as item_number,
count(*)
from t
group by cast(timestamp as date),
(case when convert(time, timestamp) >= '06:00:00' and
convert(time, timestamp) < '14:30:00'
then 1
when convert(time, timestamp) >= '14:30:00' and
convert(time, timestamp) < '23:00:00'
then 2
else 3
end),
left(barcode, 9)
order by date, shift, item_number;
This is simpler to write (and less prone to error) if you use cross apply
to define variables:
select v.date, v.shift, v.item_number,
count(*)
from t cross apply
(values (cast(timestamp as date),
(case when convert(time, timestamp) >= '06:00:00' and
convert(time, timestamp) < '14:30:00'
then 1
when convert(time, timestamp) >= '14:30:00' and
convert(time, timestamp) < '23:00:00'
then 2
else 3
end),
left(barcode, 9)
)
) v(date, shift, item_number)
group v.date, v.shift, v.item_number
order by date, shift, item_number
Upvotes: 1