2015-03-05 7 views
1

Я пытаюсь разработать запрос для проверки ввода данных пользователя, и я застрял. В основном, мы работаем с информацией о ежедневном 24-часовом смешанном образце воды. Пользователь вводит «COLDATE», который является концом составного файла и сохраняется в формате DATETIME, например «2015-03-02 04: 00: 00.000». Затем они войдут в «Compstartdate», который является varchar (8), и выглядит как «03/02/15». Наконец, они войдут в «Compstarttime», который является varchar (5) и выглядит «04:01».Проверка правильности ввода данных SQL-запрос

Не обвиняйте меня, я не установил его таким образом, и предположим, что фиксация типов данных не является вариантом.

Правило, с которым я имею дело, заключается в том, что «Compstart (дата/время)» на один день должен соответствовать «COLDATE» за предыдущий день. До сих пор я могу только выяснить, как узнать, соответствует ли «COLDATE (день) - 1 день» «Compstartdate (день)». Другими словами, я могу легко выполнять логические сравнения в одной записи, но я не знаю, как сравнивать две записи.

Кроме того, мы говорим только о 2000 записях, поэтому соображения производительности не важны, о чем свидетельствует мое использование оператора case. Под этим я подразумеваю, что решение, которое включает курсор или while-loop, было бы совершенно приемлемо для меня.

Вот что я до сих пор:

SELECT S.[SAMPNO] 
     ,S.[LOCCODE] 
     ,S.[COLDATE] 
     ,U.[Compstartdate] 
     ,U.[Compstarttime] 

    FROM [dbo].[SAMPLE] as S 
    JOIN [dbo].[SUSERFLDS] as U 
    on S.SAMPNO = U.SAMPNO 

    Where 
    Case 
     When DATEPART(DAY, Convert(VARCHAR(10),U.Compstartdate,101)) != 
      DATEPART(DAY, DATEADD(DAY, -1, S.COLDATE)) 

     Then 'Yes' 

     ELSE 'NO' 

    END ='YES' 

Edit: Позвольте мне объяснить проблему лучше. Если я собираю 24-часовой составной образец сегодня и вводя информацию о семпла в базу данных, я собираюсь ввести дату/время, когда я собрал образец (конец композитного), и дату/время начала композита , Поскольку это 24-часовая композиция, дата/время начала сегодняшней выборки должны совпадать с временем окончания (COLDATE) вчерашнего образца. Поэтому мне нужно взять два образца с одним и тем же LOCCODE, но с COLDATE на один день. Затем посмотрите, совпадает ли COLDATE для более раннего образца с Compstartdate/time более позднего образца.

Редактировать # 2: Вот несколько примеров данных.

create table [SAMPLE] (
    SAMPNO int, 
    LOCCODE char(7), 
    COLDATE datetime 
); 

create table SUSERFLDS (
SAMPNO  int, 
Compstartdate char(8), 
Compstarttime char(5) 
); 

SET DATEFORMAT mdy; 


insert into [SAMPLE] values (11,'Sample1','2015-03-02 04:00:00.000'); 
insert into [SAMPLE] values (12,'Sample1','2015-03-03 04:00:00.000'); 
insert into [SAMPLE] values (13,'Sample1','2015-03-04 04:00:00.000'); 
insert into [SAMPLE] values (14,'Sample1','2015-03-05 04:00:00.000'); 

insert into SUSERFLDS values (11, '03/01/15', '04:00'); 
insert into SUSERFLDS values (12, '03/02/15', '04:00'); 
insert into SUSERFLDS values (13, '03/03/15', '05:00'); 
insert into SUSERFLDS values (14, '03/04/15', '04:00'); 
--Compstartdate/time for SAMPNO 12 
--does match COLDATE for SAMPNO 11 
--Compstartdate/time for SAMPNO 13 
--should match COLDATE for SAMPNO 12 
+0

_ «Я могу легко делать логические сравнения в одной записи, но я понятия не имею, как сравнивать две записи». Вы имеете в виду, что можете сравнить день, но нужно также сравнить время? – Turophile

+0

Хотя верно, что мне нужно сравнить элементы даты и времени, это не то, что я имел в виду под «сравнением двух записей». Я имел в виду, что я не знаю, как сравнивать данные с одного дня с данными предыдущего дня, которые будут отображаться как отдельная запись/строка в объединенной таблице. –

+0

Я предполагаю, что это SQL Server. Какая версия? – cha

ответ

0

Наконец-то выяснилось. Вот запрос, который дает мне то, что я искал:

set dateformat mdy; 
With CTE1 as 
(
Select S1.SAMPNO as SAMPNO1 
     ,S1.COLDATE as COLDATE1 
     ,S1.LOCCODE as LOCCODE1 
     ,CAST(U1.Compstartdate +' '+ U1.Compstarttime as datetime) as Compstart1 
From [SAMPLE] as S1 join 
    [SUSERFLDS] as U1 on S1.SAMPNO = U1.SAMPNO 
), 
CTE2 as 
(
Select S2.SAMPNO as SAMPNO2 
     ,S2.COLDATE as COLDATE2 
     ,S2.LOCCODE as LOCCODE2 
     ,CAST(U2.Compstartdate +' '+ U2.Compstarttime as datetime) as Compstart2 
From [SAMPLE] as S2 join 
    [SUSERFLDS] as U2 on S2.SAMPNO = U2.SAMPNO 
) 
SELECT LOCCODE1 
     ,SAMPNO1 
     ,SAMPNO2 
     ,COLDATE1 
     ,COLDATE2 
     ,Compstart1 
From CTE1 join 
     CTE2 on LOCCODE1 = LOCCODE2 and 
      COLDATE2 = DATEADD(Day, -1, COLDATE1) 
Where Compstart1 != COLDATE2 

Позвольте мне знать, если вы видите какие фатальные недостатки.

1

Я думаю, что вы сбиты с толку - нет необходимости проходить через стол - это эффективно то, что делает соединение.

К сожалению, SQLFiddle, похоже, испытывает трудности на данный момент. Это то, что я собирался установить в качестве примера:

create table SAMPLE (
    SAMPNO int, 
    LOCCODE char(1), 
    LOCDESCR char(1), 
    LOGBATCH char(1), 
    LOGUSER char(1), 
    COLDATE datetime 
); 

create table SUSERFLDS (
SAMPNO  int, 
Compstartdate char(8), 
Compstarttime char(5) 
); 

SET DATEFORMAT mdy; 

insert into SAMPLE values (1, 'x','x','x','x','2015-03-01 04:00:00.000'); 
insert into SAMPLE values (2, 'x','x','x','x','2015-03-02 04:00:00.000'); 
insert into SAMPLE values (3, 'x','x','x','x','2015-03-03 04:00:00.000'); 
insert into SAMPLE values (4, 'x','x','x','x','2015-03-04 04:00:00.000'); 
insert into SAMPLE values (5, 'x','x','x','x','2015-03-05 04:00:00.000'); 

insert into SUSERFLDS values (2, '03/02/15', '04:00'); 
insert into SUSERFLDS values (3, '03/04/15', '04:00'); 
insert into SUSERFLDS values (4, '03/05/15', '04:00'); 
insert into SUSERFLDS values (5, '03/06/15', '05:00'); 

set dateformat mdy; 

with example as (
select CAST(compstartdate +' '+ compstarttime as datetime) as compdatetime 
from superflds) 
select * 
from sample 
where 1 = (
    select count(*) 
    from example 
    where DATEPART(dy, compdatetime) = DATEPART(dy, coldate) + 1 
    and DATEPART(hh, compdatetime) = DATEPART(hh, coldate) 
    and DATEPART(mi, compdatetime) = DATEPART(mi, coldate) 
) 

Пожалуйста, задавайте любые вопросы или добавить уточнений в комментариях.

+0

Простите, я проверил это, и это не дает мне то, что я ищу. Мне нужно сравнить сегодняшнюю дату/время начала выборки со вчерашней датой окончания/временем и найти экземпляры, где они не равны из-за ошибки ввода данных. По логике, сегодняшняя выборка (24-часовая композиция) начинается, когда заканчивается предыдущая выборка. Кроме того, LOCCODE и LOCDESC будут единственным полем, которое будет одинаковым для сегодняшних и вчерашних образцов. –

-1

Вы говорите только, что даты и время для «предыдущего дня» должны совпадать. Но тогда вы сопоставляете значения SAMPNO. Я предполагаю, что SUSERFLDS вводит время, которое должен быть выбран на следующий день.

Ваш запрос начинается хорошо, за исключением того, что ваша ссылочная таблица, по-видимому, является SUSERFLDS, так что это должна быть первая таблица в списке. Затем вы хотите сопоставить запись из SAMPLE с тем же номером выборки И с той же датой и временем.

Для сравнения вы можете повернуть время и время SAMPNO в строку того же формата, что и строка даты (mm/dd/yy), и извлечь часть даты и часть времени для сравнения со строками из SUSERFLDS , или измените строки даты и времени на значение даты и времени и сравните с датой и временем SAMPNO.

Используя последний вариант, вот запрос:

select U.[SAMPNO], 
     U.[Compstartdate], 
     U.[Compstarttime], 
     S.[LOCCODE], 
     S.[LOCDESCR], 
     S.[LOGBATCH], 
     S.[LOGUSER], 
     S.[COLDATE] 
from SUSERFLDS u 
left join SAMPLE s 
    on s.SampNo = u.SampNo 
    and s.ColDate = Cast(u.CompStartdDate + ' ' + u.CompStartTime as datetime); 

Примечание Я использую внешнее соединение. Это значит, что вы все равно увидите все записи SUSERFLDS, но с NULL, где образцы данных должны быть для этих образцов с несовпадающими датами. Это дает вам немедленное указание, где даты и время не совпадают. Вы можете добавить

where s.SampNo is null 

и вы получите только записи SUSERFLDS где образец дата и время не совпадает. В этом случае вы можете оставить все поля S.XXX в списке выбора, так как они всегда будут показывать NULL.

Однако, это на самом деле не говорит вам многого. Было бы лучше, если бы вы могли видеть фактические даты выборки, но только те, которые НЕ совпадали?

В этом случае отбросьте «левый», чтобы выполнить внутреннее соединение, и измените критерии соединения на «не равно». Как так:

select U.[SAMPNO], 
     U.[Compstartdate], 
     U.[Compstarttime], 
     S.[LOCCODE], 
     S.[LOCDESCR], 
     S.[LOGBATCH], 
     S.[LOGUSER], 
     S.[COLDATE] 
from SUSERFLDS u 
join SAMPLE s 
    on s.SampNo = u.SampNo 
    and s.ColDate <> Cast(u.CompStartdDate + ' ' + u.CompStartTime as datetime); 

Итак, теперь вы видите значения даты и времени SUSERFLDS и значения даты и времени дискретизации, но только для тех записей, которые не совпадают. Это позволяет понять, в чем проблемы.

+0

Мне нравится ваш ответ, он очень тщательный, но я боюсь, что вы, возможно, неправильно истолковали мою проблему. Я пытаюсь найти примеры, когда «Compstart (дата/время)» на один день не соответствует «COLDATE» за предыдущий день. «Compstart (дата/время)» находится в таблице SUSERFLDS, а «COLDATE» - таблица SAMPLE. Эти две таблицы связаны с «SAMPNO». –

+0

Давайте посмотрим, смогу ли я еще больше упростить эту проблему. Каждый день появляется новый образец, и он получает уникальный SAMPNO. Каждый образец имеет COLDATE, который является концом 24-часового композитного материала. У каждого образца также есть поля для даты и времени, когда был запущен 24-часовой композит.Логично, что ** начало ** сегодняшнего образца должно быть таким же, как ** конец ** образца вчера, справа. Поэтому я пытаюсь найти ошибки при вводе данных, когда начальная и конечная дата/время не совпадают. Ясно, как грязь, не так ли? –

+0

Вы говорите, что для каждой записи образца есть несколько записей SUSERFLDS? И чтобы вы просто удостоверились, что есть один из них, который имеет ту же дату и время, что и запись образца? – TommCatt

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