Выберите возраст диапазона с единицей измерения в том же поле - PullRequest
0 голосов
/ 06 октября 2011

Я работаю над таблицей, где возраст человека указан в строковом поле, где он имеет следующий формат: (сумма UnitOfMeasurement)

1 year old = 1 y
11 months old = 11 m
5 Days old = 5 d

Я пытаюсь выполнить поиск по возрасту. Возможно ли это с помощью SQL-запроса, в котором сначала будут указаны дни (d), а затем месяцы (м) и годы (у)?

База данных находится на SQL Server 2008, но, вероятно, запрос будет выполнен на Access, поскольку он используется для источника записей отчета.

Ответы [ 3 ]

0 голосов
/ 06 октября 2011

Первое, что я хотел бы сделать в вашей ситуации, это попытаться очистить грязное поле возраста и стандартизировать его.Быстрый старт может состоять в том, чтобы создать запрос, в котором вы разделяете значение возраста и единицу возраста, используя такие выражения, как:

age_unit: Right([age], 1)

и

age_value: Val([age])

Если вы затем сортируете поage_unit и age_value, вы получите все возрасты, отсортированные правильно (при условии, что возраст в днях всегда меньше, чем возраст в месяцах, который, в свою очередь, всегда меньше, чем возраст в годах).Обратите внимание, что вы должны сначала отсортировать по единице, а затем по значению.

Если вы хотите вернуть возраст между определенным минимумом и максимумом, это не проблема, если вы придерживаетесь одной единицы, например всех возрастов между5 лет и 15 лет.Просто введите «y» в качестве критерия в поле «age_unit» (при условии, что вы используете визуальный построитель запросов) и введите «между 5 и 15» в поле «age_value».

Если вы 'Перемешивание единиц («все возрасты от 6 месяцев до 2 лет») становится немного сложнее.В этом случае вам нужно будет сделать следующее:

В одну строку критериев вы должны ввести следующие значения для каждого поля:

age_unit: "m"

age_value:> = 6

И затем в следующей строке критериев:

age_unit: "y"

age_value: <= 2 </p>

Это вернетвсе возрасты, имеющие единицу «m» и значение> = 6, ИЛИ имеющие единицу «у» со значением <= 2. </p>

Другим несколько более простым решением было бы преобразование всех возрастов в стандартную единицу, такую ​​как годы,выполнив несколько простых вычислений, например, разделите значения единиц измерения «d» на 365,25 и разделите значения единиц измерения «m» на 12. Затем создайте новое поле в своей таблице для новых стандартизированных данных о возрасте.

0 голосов
/ 06 октября 2011

1.Это поле не имеет атомных значений . Это означает, что ваша таблица не в 1NF.

Вы должны разбить поле Age на 2 столбца с атомарными значениями: IntervalType (CHAR(1)... CHECK(IntervalType IN ('d','m','y')) и IntervalValue (INT; 1,2 и т. Д.). Таким образом, вместо Table (..., Age) вы можете использовать Table (..., IntervalType, IntervalValue) и

SELECT *
    ,CONVERT(VARCHAR(10),IntervalValue)
    +' '+CASE IntervalType WHEN 'd' THEN 'day' WHEN 'm' THEN 'month' WHEN 'y' THEN 'year' END
    +CASE WHEN IntervalValue > 1 THEN 's' ELSE '' END
    +' old = '
    +CONVERT(VARCHAR(10),IntervalValue)
    +' '+IntervalType
FROM table

2.Как вы сортируете эти два значения: 30 d и 1 month? Один месяц может иметь от 28 до 31 дня.

3. SQL Server решение:

DECLARE @TestData TABLE
(
     Age VARCHAR(25) NOT NULL
    ,IntervalValue AS CONVERT(INT,LEFT(Age,CHARINDEX(' ',Age))) PERSISTED
    ,IntervalType AS RIGHT(Age,1) PERSISTED
);
INSERT  @TestData
VALUES
 ('1 year old = 1 y')
,('2 years old = 2 y') 
,('11 months old = 11 m')
,('30 Days old = 30 d')
,('5 Days old = 5 d');

SELECT  *
FROM    @TestData a
ORDER BY a.IntervalType, a.IntervalValue;
0 голосов
/ 06 октября 2011

Лучше всего было бы создать новый столбец с реальным значением DATETIME.Затем вы могли бы написать код, такой как оператор CASE, чтобы помочь преобразовать строку в DATETIME.После завершения ваши расчеты станут намного проще.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...