2015-12-21 1 views
0

У меня есть проект, над которым я работаю, и каждый день нужно знать определенные данные и данные. Наша компания обрабатывает элементы и делает штамп даты и времени для каждого из них в формате 2015-09-16 07: 15: 18.000. У них также есть еще один столбец, где они упоминают день недели, который он должен обрабатывать. В этом случае это будет среда. Эта информация хранится в БД как «SU», «MO», «TU», «WE», «TH», «FR», «SA». В середине дня они могут решить отметить вещи, но прекратить производство, если они не были до этого времени. Это называется отключением. Таким образом, все, что помечено после отсечения, теперь будет использовать следующий день недели в столбце. Так что если отрезок в 12:35:05, то 2015-09-16 15: 04: 11.000 теперь хранится как «TH», даже если он был помечен в среду.Самый эффективный способ получить определенные строки в PHP и MS SQL на основе конкретных условий

Исторически они никогда не сохраняли время отсечения в базе данных. Теперь им нужно делать это каждый день с 01 января 2015 года. Поэтому мне нужно иметь возможность возвращать около 313 строк (у нас нет данных по воскресеньям), где наибольшая отметка времени для дня соответствует дню столбца и возврату те результаты в PHP. Но если кто-то может сделать это в чистом транзакционном SQL, который будет работать и для меня.

У меня было грубое время, чтобы это произошло, и я был бы рад получить эти результаты из данных данных.

Образец возвращенных результатов будет выглядеть следующим образом:

Date_In     Week_Day 
----------------------- -------- 
2015-01-01 12:15:18.000 TH 
2015-01-02 12:13:23.000 FR 
2015-01-03 12:45:56.000 SA 
2015-01-05 12:09:11.000 MO 
2015-01-06 11:54:49.000 TU 
2015-01-07 12:14:30.000 WE 
2015-01-08 12:15:28.000 TH 
2015-01-09 12:05:11.000 FR 
2015-01-10 12:53:58.000 SA 
2015-01-12 12:01:12.000 MO 
ect.. 
+0

Если я прочитал это правильно, вы хотите, чтобы запрос, который выбирает строки с временем, большим, чем время отсечки, должен иметь столбец 'Week_Day', обновленный до следующего дня? – Twisty

+0

На самом деле это было бы меньше, чем время отсечения. По прошествии времени после отрезанных часов и точно не представлялось, когда было отрезано. –

+0

@BradMetcalf в примере, который вы дали, отсечение будет 12: 35: 05.000. Учитывая данные примера, это будет все строки, но 2, правильно? Мы игнорируем эти 2 ('2015-01-03 12: 45: 56.000 SA' и' 2015-01-10 12: 53: 58.000 SA') право? – Twisty

ответ

2

Здесь вы идете, чистый TSQL. Substring с datename.

select substring(datename(dw,convert(date,'2015-01-01 12:15:18.000')),0,3) -- returns 'TH' 

--get records where date matches weekday 
select * from mytable where substring(datename(dw,convert(date,Date_In)),0,3) = Week_Day 

И что-то, как это должно дать вам результаты, где дата соответствует макс будний

create table #test(
 
Date_In datetime, 
 
Week_Day varchar(2) 
 
) 
 

 
insert into #test(Date_In,Week_Day) values ('2015-01-01 12:15:18.000','TH'), 
 
('2015-01-02 12:13:23.000','FR'), 
 
('2015-01-03 12:45:56.000','SA'), 
 
('2015-01-05 12:09:11.000','MO'), 
 
('2015-01-06 11:54:49.000','TU'), 
 
('2015-01-07 12:00:30.000','TU'), 
 
('2015-01-07 12:14:30.000','WE'), 
 
('2015-01-08 12:15:28.000','TH'), 
 
('2015-01-09 12:05:11.000','FR'), 
 
('2015-01-10 12:53:58.000','SA'), 
 
('2015-01-12 12:01:12.000','MO') 
 
    
 
SELECT Max(Cast(#test.date_in AS DATE)) AS Date_In, 
 
     Max(#test.week_day)    AS Week_day 
 
FROM #test 
 
     LEFT JOIN #test b 
 
       ON b.week_day = #test.week_day 
 
       AND Cast(b.date_in AS DATE) = Cast(#test.date_in AS DATE) 
 
WHERE Substring(Datename(dw, CONVERT(DATE, Cast(#test.date_in AS DATE))), 0, 3) 
 
     = 
 
     #test.week_day 
 
GROUP BY Cast(#test.date_in AS DATE)

+0

Это просто вернет все строки, не так ли? – ZLK

+0

@ZLK Нет 3 запроса, каждый из которых работает с другими результирующими наборами. сначала мы группируем таблицу и получаем наивысшую дату, тогда мы обрезаем ее до тех пор, пока не будет дней, когда максимальная дата совпадает с будним днем, а затем, наконец, мы используем эти дни в качестве ссылки, чтобы получить остальную часть данных. Его не гарантируют копирование и вставка, но это лучшее, что я могу сделать без скрипки. – kurt

+0

Это не работает для меня. Он возвращает 36 000 строк из 85 000 строк в таблице. Решение не должно превышать 313 результатов. –

1

Это должно произвести желаемый результат.

; WITH T AS (SELECT [Date_In], [Week_Day], ROW_NUMBER() OVER (ORDER BY [Date_In]) RN 
    FROM table) 
SELECT C1.[Date_In], C1.[Week_Day] 
FROM T C1 
LEFT JOIN T C2 ON C2.RN -1 = C1.RN 
WHERE C1.[Week_Day] <> C2.[Week_Day] OR C1.RN = (SELECT MAX(RN) FROM T) 
ORDER BY C1.[Date_In] 
+0

Это работает. Он возвращает 299 результатов за этот незавершенный год. И результаты соответствуют моей ручной проверке. Единственная проблема - это 4 минуты и 29 секунд. Поэтому, пока он не будет работать в реальном времени, я могу взять результаты и поместить их в другую таблицу, чтобы делать то, что мне нужно сделать. Если никто не сможет сделать это более эффективно, я буду отмечать это как ответ. Благодаря! –

+0

Если ваш стол большой, он сделает это, вы можете сократить время, затрачиваемое на выбор, только выбрав столбцы, которые вам нужно выбрать. Например, редактирование должно быть быстрее (но если вы переходите через тысячи и тысячи строк, это может быть медленным). – ZLK

+0

Почему бы не использовать курсоры? – AlexanderMP

0

Это вопрос выбора максимального значения для этого DateTime на каждый день и каждый отмечается день недели, до тех пор, как дата имеет один и тот же день недели, как маркированной день.

SELECT max(date_in), week_day FROM table 
WHERE SUBSTRING (datename(dw, date_in), 1, 2) = week_day 
GROUP BY Week_Day, CONVERT(date, date_in) 

Я не могу его правильно протестировать, но это должно сработать. Может быть, синтаксическая ошибка или что-то еще. Дайте мне знать, если вы попробуете.

Смежные вопросы