24 декабря Архивач восстановлен после серьёзной аварии. К сожалению, значительная часть сохранённых изображений и видео была потеряна. Подробности случившегося. Мы призываем всех неравнодушных помочь нам с восстановлением утраченного контента!
sage

Олимпиадка

 Аноним OP 06/07/15 Пнд 21:30:28 #1 №510053 
14362074285180.jpg
Каждый уважающий себя программист должен кое-что знать о реляционных СУБД и языке запросов SQL (ORM в вашем любимом языке / фреймворке не всесилен) — ведь разработка сколько-нибудь серьёзного приложения не обходится без базы данных.

Вскукареки от школьников о NoSQL не принимаются (ну, сначала почитайте, что такое ACID, BASE — потом приходите).

ОТВЕТЫ ПИШЕМ ПОД СПОЙЛЕРОМ, ЧТОБЫ НЕ ЛИШАТЬ УДОВОЛЬСТВИЯ ДРУГИХ АНОНОВ

Олимпиадка:



Вопрос 1
Имеется таблица:
create table users (
user_id integer primary key,
user_name text not null,
is_male boolean not null
)
Напишите SQL запрос, который вывел бы одной строчкой кол-во мальчиков и девочек



Вопрос 2
Имеется таблица-справочник городов:
create table cities (
city_id integer primary key,
city_name text not null
)
Напишите SQL запрос, который бы удалял дублирующиеся по имени города



Вопрос 3
Имеется таблица
create table staff (
employee_id integer primary key,
department_id integer not null,
salary integer not null
)
Напишите SQL запрос, выводящий для каждого отдела первую тройку сотрудников с наибольшей зарплатой



Вопрос 4
У вас выполняются две транзакции в следующем порядке:
Транзакция-1:
UPDATE accounts SET balance = balance + 100.00 WHERE acctnum = 11111;
Транзакция-2:
UPDATE accounts SET balance = balance + 100.00 WHERE acctnum = 22222;
UPDATE accounts SET balance = balance - 100.00 WHERE acctnum = 11111;
Транзакция-1:
UPDATE accounts SET balance = balance - 100.00 WHERE acctnum = 22222;
К чему это в результате приведет? И что в таком случае делать?



Вопрос 5
Что хорошего и плохого в хранимых процедурах?



Вопрос 6
У вас медленно работает запрос, ваши действия.



Вопрос 7
В таблице t( i int ) n записей. Значения в строках заполнены равномерно из [ 1; m ].
Оцените, сколько записей в таких случаях будет возвращать запрос.

select 1 from t t1, t t2 where t1.i = t2.i

sageАноним 06/07/15 Пнд 21:32:16 #2 №510059 
С какой стати я должен решать твою домашку?
Аноним 06/07/15 Пнд 21:35:00 #3 №510061 
>>510053
SELECT (SELECT COUNT() FROM users WHERE is_male = true) AS boys,
(SELECT count(
) FROM users WHERE is_male = false) AS girls
Аноним 07/07/15 Втр 00:52:49 #4 №510157 
Это же твоя домашка, да? Или говно какое-то с курсиков для даунов? Или ты куда-то на стажировку пытаешься устроится и тебе прислали такие вопросы для аутистов?

Потому что это даже студентота всё решит. Олимпиадка у него, лолд.
Аноним 08/07/15 Срд 13:29:32 #5 №510927 
1. select (select count() from users where is_male = true), (select count() from users where is_male = false);

2. delete from cities where city_id in (select t1.city_id from cities t1, cities t2 where t1.city_name = t2.city_name and t1.city_id > t2.city_id);

3. select t1.employee_id, t1.department_id, t1.salary from staff t1 where t1.employee_id in (select t2.employee_id from staff t2 where t2.department_id = t1.department_id order by t2.salary desc limit 3);

4. Если выбран такой уровень изоляции, что транзакции видят друг друга, то возможна взаимоблокировка, которую разрешит СУБД, оборвав более позднюю транзакцию. Надо повысить уровень изоляции до такого, чтобы транзакции не видели друг друга

5. Хороши скоростью их запуска, так как хранятся в предкомпилированном виде. Плохи тем, что в большинстве СУБД хранимки пишут на кривом и ограниченном языке

6. EXPLAIN ANALYZE, а дальше все зависит от того, что он выдаст. Может быть, переписать запрос, может быть, добавить индексов, а может, и схему БД менять надо

7. 2*floor((n-1)/m)

Насчет 7ого и 4ого ответа не уверен до конца в своей правоте.
Аноним 08/07/15 Срд 15:06:12 #6 №511001 
>>510053
Пошел нахуй, говно.
Аноним 09/07/15 Чтв 00:47:52 #7 №511312 
>>510053
Под оракл. При желании можно переписать на обычный sql.
1)
SELECT
COUNT(DECODE(is_male,TRUE,1)) "Кол-во мальчиков",
COUNT(DECODE(is_male,FALSE,1)) "Кол-во девочек"
FROM users;


2)
DELETE FROM cities c1
WHERE c1.city_id > ANY(SELECT c2.city_id FROM cities c2 WHERE c2.city_name = c1.city_name);


3) Вот это хуй знает как без аналитических функций сделать.
Если ровно тройка, то запрос ниже. Если просто сотрудники с тремя максмальными зарплатами, то использовать RANK()
SELECT employee_id FROM (
SELECT s.,
ROW_NUMBER() OVER(PARTITION BY department_id ORDER BY salary DESC, employee_id ASC /
для однозначности результата*/) rnum
)
WHERE rnum <= 3;


4) Оракл как-то разрешает дедлоки, но особо не интересовался этой темой. Знаю, что одну из транзакций он откатит на шаг назад и кинет исключение.

5) Предкомпилированный запрос, который не будет лишний раз парситься. Минусы в самом языке.

6) Посмотреть план выполнения, подумать.

7) Минимум - n.
А в среднем,
E count(select 1 from t t1, t t2 where t1.i = t2.i) =
\sum_{k=1}^{m} E count(select 1 from t t1, t t2 where t1.i = t2.i AND t1.i = k) =
\sum_{k=1}^{m} E (count(select 1 from t t1 where t1.i = k)^2)

count(select 1 from t t1 where t1.i = k) - если записей в таблице много, то можно приблизить по ЦПТ для бернулливских случайных величин к нормальной случайной величиной N c E(N) = n/m и D(N) = n(m-1)/m.
D(X) = E(X^2) - E(X)^2, откуда
E(N^2) = E (count(select 1 from t t1 where t1.i = k)^2) = (n/m)(m - 1 + n/m)

Итоговая сумма = n(m - 1 + n/m), если я нигде не напутал
Аноним 09/07/15 Чтв 01:29:13 #8 №511340 
>>511312
> 7) Таки проебался в одном месте. Начну с него.
D(N) = n(m-1)/m2.
> D(X) = E(X^2) - (E(X))2, откуда
> E(N2) = E (count(select 1 from t t1 where t1.i = k)^2) = n(m-1)/m^2 + (n/m)^2 = n(n + m - 1)/m^2

> Итоговая сумма = (n/m)(n + m - 1)
sageАноним 10/07/15 Птн 00:27:33 #9 №512090 
>>510053
>ну, сначала почитайте, что такое ACID, BASE

Писав эту хуету, ты, скорее всего, подразумевал, что NoSQL не может в ACID. А это значит, что ты не знаешь про NoSQL ровно нихуя.
Пиздуй на пары короче.
sageАноним 10/07/15 Птн 17:46:33 #10 №512449 
14365395939740.jpg
>>510053
Как вы уже заебали этими SQL-запросами на собеседованиях.
Аноним 10/07/15 Птн 18:38:56 #11 №512484 
14365427362090.png
>>512449
Так же, как и вы.
Аноним 11/07/15 Суб 00:48:50 #12 №512709 
>>512449
Халява же.
Аноним 12/07/15 Вск 19:26:36 #13 №513483 
14367183960790.jpg
>>510053
И где такой хуйни научиться? Только, пожалуйста, хочу выучить эту вс. теорию релиционых баз на sqlite. Книгу, ресурс, что угодно. Или все равно надо учить MySQL?
Аноним 12/07/15 Вск 19:34:12 #14 №513485 
>>513483
алан бьюли изучаем sql скачать
том кайт oracle для профессионалов скачать
http://lurkmore.to/Sql.ru
Аноним 14/07/15 Втр 16:16:49 #15 №514455 
>>510053
> Значения в строках заполнены равномерно из [ 1; m ].
что за быдло-мутант писал этот текст?
Аноним 14/07/15 Втр 17:21:55 #16 №514494 
>>513485
двачую. алан бьюли хорошая книжка. я когда-то читал оригинал. но товарищ говорил, что у нее и перевод на русский неожиданно хороший, прям на редкость хороший
Аноним 27/07/15 Пнд 19:37:35 #17 №521635 
Вот вопрос.
Есть две таблицы A и B. Они описывают одни и те же сущности, только половина полей в A, а вторая — в B. Другими словами

Таблица A
id [int]
second_name [text]
given_name [text]
father_name [text]

Таблица B
id [int]
birthdate [date]

И один и тот же человек есть и в B и в A.

Теперь вопрос:
Какой принцип это нарушает? Я думал, что это нарушение одной из нормальных форм, но я перечитал сегодня определение всех, и я не смог такую найти
Аноним 28/07/15 Втр 13:17:56 #18 №521973 
>>510053

1 вопрос.
select is_male, count(*) from users group by is_male;

2 вопрос.
DELETE FROM cities
WHERE city_id IN (SELECT city_id
FROM (SELECT city_id,
ROW_NUMBER() OVER (partition BY city_name ORDER BY city_id) AS rnum
FROM cities) t
WHERE t.rnum > 1);

Аноним 28/07/15 Втр 13:32:22 #19 №521991 
7 вопрос

Вообще select 1 возвращает 1 запись не?
Аноним 28/07/15 Втр 13:33:57 #20 №521992 
Вопрос 6

Перейду на mongodb )))
А так если некуда деваться то смотрим EXPLAIN <запрос> че с ним не так, где тупит, может индекса не хватает, посмотрим настройки субд, так то очень общий вопрос.
Аноним 28/07/15 Втр 13:36:42 #21 №521995 
Вопрос 5

Плохо поддаются версионированию, однако есть решения просто хранить их в sql файлике под гитом. Еще мы таким образом бизнес логику переносим в бд что не всегда хорошо.

Хорошо что они прямо на базе выполняются профит в скорости, и синтаксис имеют тот же (sql), удобно короче.
Аноним 28/07/15 Втр 13:39:16 #22 №521997 
Вопрос 4

Deadlock detected, не?

одна транзакция откатится.
Аноним 29/07/15 Срд 00:16:27 #23 №522451 
>>521991
Нет

мимо-проходил
Аноним 29/07/15 Срд 02:10:43 #24 №522493 
>>510053
Ох блядь.

SELECT
(SELECT COUNT() FROM users WHERE is_male=true) AS boys,
(SELECT COUNT(
) FROM users WHERE is_male=false) AS girls

DELETE FROM cities AS a JOIN cities AS b
WHERE a.city_name = b.city_name AND a.city_id > b.city_id

SELECT department_id, employee_id, salary
FROM
(SELECT department_id, employee_id, salary,
rank() OVER (PARTITION BY department_id ORDER BY salary DESC) AS pos
FROM staff)
WHERE pos <= 3
ORDER BY department_id ASC, salary DESC

Зависит от СУБД. На нормальных движках такое выполняется корректно, оба аккаунта в конечном итоге получат 0. Если нет, то играемся с уровнями изоляции, или делаем SELECT FOR UPDATE.

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

Посмотреть DESCRIBE, расставить индексы, применить партишенинг, добавить избыточности.

Ровно N.

Выходить в понедельник или вы мне перезвоните?
comments powered by Disqus

Отзывы и предложения