简体   繁体   中英

Grouping by multiple parameters in SQL Server

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:

  • Shift 1 is from 06:00:00 to 14:29:59
  • Shift 2 is from 14:30:00 to 22:59:59
  • Shift 3 is from 23:00:00 to 05:59:59

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)

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

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM