Добро пожаловать в форум, Guest  >>   Войти | Регистрация | Поиск | Правила | В избранное | Подписаться
Все форумы / Microsoft SQL Server Новый топик    Ответить
Топик располагается на нескольких страницах: [1] 2 3   вперед  Ctrl      все
 Тесты при  [new]
MagistrR
Member

Откуда:
Сообщений: 31
При приеме на работу мне были предложены задания для решения. Но не все они были решены правильно. И я бы хотел что бы знатоки подсказали правильное решение, что бы можно было их разобрать для повышения своего уровня.
Задание 1.
Имеется таблица
create table T (A int not null primary key, b int, c int, d float)
Как сократить время выполнения такого запроса
select b, sum(d) from T 
group by b?


Я предложил создать индекс в таблице по полю d. Скорее всего, я был неправ.
14 июн 11, 15:17    [10810919]     Ответить | Цитировать Сообщить модератору
 Re: Тесты при  [new]
Гадя Петрович
Member

Откуда: планета Плюк, 215 в тентуре, галактика Кин-дза-дза в Спирали
Сообщений: 52912
MagistrR
Я предложил создать индекс в таблице по полю d. Скорее всего, я был неправ.
я бы сделал по b с включением d
14 июн 11, 15:18    [10810928]     Ответить | Цитировать Сообщить модератору
 Re: Тесты при  [new]
MagistrR
Member

Откуда:
Сообщений: 31
Гадя Петрович,
Т.е. создать индекс по двум полям, по b и d?
14 июн 11, 15:26    [10810967]     Ответить | Цитировать Сообщить модератору
 Re: Тесты при  [new]
индекс
Guest
MagistrR,

по полю b скорее вы предложили.
попробуйте вспомнить :)
14 июн 11, 15:28    [10810988]     Ответить | Цитировать Сообщить модератору
 Re: Тесты при  [new]
MagistrR
Member

Откуда:
Сообщений: 31
индекс,
Нет, я предложил индекс по полю d. Я хотел предложить по полю b, но увидел что оно типа int и решил, что лучше индекс по полю d, т.к. оно float.
14 июн 11, 15:34    [10811041]     Ответить | Цитировать Сообщить модератору
 Re: Тесты при  [new]
Гадя Петрович
Member

Откуда: планета Плюк, 215 в тентуре, галактика Кин-дза-дза в Спирали
Сообщений: 52912
MagistrR
Гадя Петрович,
Т.е. создать индекс по двум полям, по b и d?
нет
include
14 июн 11, 15:36    [10811052]     Ответить | Цитировать Сообщить модератору
 Re: Тесты при  [new]
egaraev
Member

Откуда:
Сообщений: 63
Индекс по b включающий d я думаю самый подходящий.
14 июн 11, 15:51    [10811124]     Ответить | Цитировать Сообщить модератору
 Re: Тесты при  [new]
MagistrR
Member

Откуда:
Сообщений: 31
Спасибо всем, значит мне надо больше читать про индексы.
Теперь следующая задача.

Напишите запрос, показывающий все отличия таблицы @tt от таблицы @t
declare @t table(x int NOT NULL, y int) 
declare @tt table(x int NOT NULL, y int) 
insert into @t values(1, 3) 
insert into @t values(2, 2) 
insert into @t values(3, NULL) 
insert into @t values(5, NULL)
insert into @tt values(1, 3)
insert into @tt values(3, NULL)
insert into @tt values(4, 3)

Мой ответ был
select * into #ttt from @t
  union all
select * from @tt

select x,y 
     from #ttt
   group by x,y
   having count(*) = 1

Может есть более красивый способ?
14 июн 11, 16:08    [10811265]     Ответить | Цитировать Сообщить модератору
 Re: Тесты при  [new]
invm
Member

Откуда: Москва
Сообщений: 9825
select * from @tt
except
select * from @t
Касаемо первого вопроса -- ускорить можно создав из
select b, sum(d) from T 
group by b
индексированное представление
14 июн 11, 16:17    [10811344]     Ответить | Цитировать Сообщить модератору
 Re: Тесты при  [new]
Критик
Member

Откуда: Москва / Калуга
Сообщений: 35374
Блог
>>Мой ответ был

full join
14 июн 11, 16:39    [10811554]     Ответить | Цитировать Сообщить модератору
 Re: Тесты при  [new]
iap
Member

Откуда: Москва
Сообщений: 47142
MagistrR
Напишите запрос, показывающий все отличия таблицы @tt от таблицы @t
.............................................
Мой ответ был
Это ответ не на тот вопрос. IMHO.
invm
select * from @tt
except
select * from @t
  • EXCEPT возвращает только различающиеся записи.
  • Он вернёт только записи, которые есть в @tt и нет в @t. А разве записи, которых нет в @tt и есть в @t, не являются "отличием"?
    Так что, в общем случае не катит. Не соответствует условию задачи. IMHO.
    SET NOCOUNT ON;
    declare @t table(x int NOT NULL, y int) 
    declare @tt table(x int NOT NULL, y int) 
    insert into @t values(1, 3) 
    insert into @t values(2, 2) 
    insert into @t values(3, NULL) 
    insert into @t values(5, NULL)
    insert into @tt values(1, 3)
    insert into @tt values(3, NULL)
    insert into @tt values(4, 3);
    
    SELECT 'лишние'[@tt по сравнению с @t],x,y
    FROM @tt
    WHERE NOT EXISTS(SELECT x,y INTERSECT SELECT x,y FROM @t)
    UNION ALL
    SELECT 'недостающие',x,y
    FROM @t
    WHERE NOT EXISTS(SELECT x,y INTERSECT SELECT x,y FROM @tt);
  • 14 июн 11, 16:43    [10811576]     Ответить | Цитировать Сообщить модератору
     Re: Тесты при  [new]
    invm
    Member

    Откуда: Москва
    Сообщений: 9825
    iap,

    Зависит от того, как трактовать "отличие @tt от @t". ИМХО, мой вариант тоже имеет право на жизнь.
    14 июн 11, 16:49    [10811631]     Ответить | Цитировать Сообщить модератору
     Re: Тесты при  [new]
    iap
    Member

    Откуда: Москва
    Сообщений: 47142
    invm
    iap,

    Зависит от того, как трактовать "отличие @tt от @t".
    Согласен.
    Как обычно, автор задачи не заморачивается.
    Сомневаюсь, что он сам понимает, чего хочет.
    14 июн 11, 17:05    [10811777]     Ответить | Цитировать Сообщить модератору
     Re: Тесты при  [new]
    Гавриленко Сергей Алексеевич
    Member

    Откуда:
    Сообщений: 37254
    iap
    Как обычно, автор задачи не заморачивается.
    Сомневаюсь, что он сам понимает, чего хочет.
    Автор тех задач, которые даются при приеме на работу, обычно хочет, чтобы кандидат порассуждал, поперебирал разные варианты, в общем, подумал немного над задачей, которая может выглядеть идиотской на первый (и не только на первый) взгляд.
    14 июн 11, 17:08    [10811792]     Ответить | Цитировать Сообщить модератору
     Re: Тесты при  [new]
    Гадя Петрович
    Member

    Откуда: планета Плюк, 215 в тентуре, галактика Кин-дза-дза в Спирали
    Сообщений: 52912
    Гавриленко Сергей Алексеевич
    iap
    Как обычно, автор задачи не заморачивается.
    Сомневаюсь, что он сам понимает, чего хочет.
    Автор тех задач, которые даются при приеме на работу, обычно хочет, чтобы кандидат порассуждал, поперебирал разные варианты, в общем, подумал немного над задачей, которая может выглядеть идиотской на первый (и не только на первый) взгляд.
    чаще автор таких задач хочет, чтобы от него HR поскорей уже отвалила со своими задачами :)
    14 июн 11, 17:14    [10811830]     Ответить | Цитировать Сообщить модератору
     Re: Тесты при  [new]
    iap
    Member

    Откуда: Москва
    Сообщений: 47142
    Гавриленко Сергей Алексеевич
    iap
    Как обычно, автор задачи не заморачивается.
    Сомневаюсь, что он сам понимает, чего хочет.
    Автор тех задач, которые даются при приеме на работу, обычно хочет, чтобы кандидат порассуждал, поперебирал разные варианты, в общем, подумал немного над задачей, которая может выглядеть идиотской на первый (и не только на первый) взгляд.
    Думаю, в данном случае расставлена ловушка в виде значений NULL
    Критик
    full join
    SET NOCOUNT ON;
    declare @t table(x int NOT NULL, y int) 
    declare @tt table(x int NOT NULL, y int) 
    insert into @t values(1, 3) 
    insert into @t values(2, 2) 
    insert into @t values(3, NULL) 
    insert into @t values(5, NULL)
    insert into @tt values(1, 3)
    insert into @tt values(3, NULL)
    insert into @tt values(4, 3);
    
    SELECT
     CASE WHEN tt.x IS NULL THEN 'недостающие' ELSE 'лишние' END[сравнение @tt с @t],
     ISNULL(tt.x,t.x) x,
     CASE WHEN tt.x IS NULL THEN t.y ELSE tt.y END y
    FROM @tt tt FULL JOIN @t t ON EXISTS(SELECT tt.x,tt.y INTERSECT SELECT t.x,t.y)
    WHERE tt.x IS NULL OR t.x IS NULL;
    14 июн 11, 18:24    [10812250]     Ответить | Цитировать Сообщить модератору
     Re: Тесты при  [new]
    MagistrR
    Member

    Откуда:
    Сообщений: 31
    Пропал не на долго.
    Ещё одно задание:
    Напишите быстрейший запрос вывода всех сотрудников работавших в определённый период времени.
    @date_start datetime
    @date_end datetime

    Исходная таблица:
    Table(user_id int,
    date_start datetime,
    date_end datetime)

    Моё решение:
    SELECT user_id,
           date_start,
           date_end
      FROM Table t
      WHERE convert(date_end AS DATE) >= convert(@date_start AS DATE) AND convert(date_start AS DATE) <= convert(@date_end AS DATE)
      GROUP BY user_id, date_start, date_end

    Понятно, что это не быстрейший запрос, но нужно же было дать ответ.
    15 июн 11, 10:33    [10814222]     Ответить | Цитировать Сообщить модератору
     Re: Тесты при  [new]
    WarAnt
    Member

    Откуда: Питер
    Сообщений: 2423
    MagistrR,

    а зачем надо было приводить к date? типы данных одинаковые, а так вы убили оптимизатору возможность успользовать индексы если они есть.
    15 июн 11, 10:45    [10814298]     Ответить | Цитировать Сообщить модератору
     Re: Тесты при  [new]
    MagistrR
    Member

    Откуда:
    Сообщений: 31
    WarAnt,

    Я же не знаю содержаться ли в переменных периода ещё и время. Поэтому и привел к date.
    15 июн 11, 10:49    [10814323]     Ответить | Цитировать Сообщить модератору
     Re: Тесты при  [new]
    WarAnt
    Member

    Откуда: Питер
    Сообщений: 2423
    MagistrR
    WarAnt,

    Я же не знаю содержаться ли в переменных периода ещё и время. Поэтому и привел к date.


    ну дак тем более зачем мудрить:) ти к тому же так сказано период времени, а если этот период 10 минут ваш запрос уже неправильно отработает
    15 июн 11, 10:51    [10814339]     Ответить | Цитировать Сообщить модератору
     Re: Тесты при  [new]
    invm
    Member

    Откуда: Москва
    Сообщений: 9825
    MagistrR,

    Ну у вас же в задаче не указана гранулярность интервала времени. Если я захочу получить данные за час?
    15 июн 11, 10:54    [10814358]     Ответить | Цитировать Сообщить модератору
     Re: Тесты при  [new]
    stimpi
    Member

    Откуда: Киев, Украина
    Сообщений: 662
    денормализировать таблицу, добавить колонку Ticks (date_end - date_start)
    далее создать индекс по (date_start, ticks)
    ну и получить ваш период в тиках и искать по date_start + ticks.
    15 июн 11, 11:09    [10814476]     Ответить | Цитировать Сообщить модератору
     Re: Тесты при  [new]
    MagistrR
    Member

    Откуда:
    Сообщений: 31
    WarAnt,

    Т.е. Вы считаете, что мой запрос написан верно за исключением приведения к date?
    15 июн 11, 11:33    [10814679]     Ответить | Цитировать Сообщить модератору
     Re: Тесты при  [new]
    Гадя Петрович
    Member

    Откуда: планета Плюк, 215 в тентуре, галактика Кин-дза-дза в Спирали
    Сообщений: 52912
    а группировка зачем?
    15 июн 11, 11:36    [10814706]     Ответить | Цитировать Сообщить модератору
     Re: Тесты при  [new]
    _ч_
    Member

    Откуда:
    Сообщений: 1446
    MagistrR
    Напишите быстрейший запрос вывода всех сотрудников работавших в определённый период времени.

    Вот тут уже не понятно требуется или нет выводить поля date_start, date_end или достаточно только user_id.

    А чем отличается:
    MagistrR
    Моё решение:
    SELECT user_id,
           date_start,
           date_end
      FROM Table t
      WHERE convert(date_end AS DATE) >= convert(@date_start AS DATE) AND convert(date_start AS DATE) <= convert(@date_end AS DATE)
      GROUP BY user_id, date_start, date_end


    от:

    Моё решение:
    SELECT DISTINCT user_id,
           date_start,
           date_end
      FROM Table t
      WHERE convert(date_end AS DATE) >= convert(@date_start AS DATE) AND convert(date_start AS DATE) <= convert(@date_end AS DATE)
      
    ?
    15 июн 11, 11:40    [10814735]     Ответить | Цитировать Сообщить модератору
    Топик располагается на нескольких страницах: [1] 2 3   вперед  Ctrl      все
    Все форумы / Microsoft SQL Server Ответить