Все технические форумы на одном сайте Удобный поиск информации с популярных форумов в одном месте
Вопрос: Стиль написания условий в запросах. Как быстрее?

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

SELECT * FROM material m
WHERE m.document_num = ISNULL(@DocumentNum, m.document_num)

SELECT * FROM material m
WHERE @DocumentNum IS NULL OR m.document_num = @DocumentNum


Чем отличаются эти ситуации? Я заметил, что в первом случае сервер умеет строить параллельный план. Первый запрос выполняется существенно быстрее. Однако, если параллелизм не прокатил, то будет чуть-чуть быстрее второй запрос.
Ответ: TaPaK,
, так я так и не понял. У вас реально таких запросах на продакшене на больших таблицах нету или есть?
Вопрос: Застрял на одном уровне сложности в написании запросов.

Всем привет!
Изучаю MS SQL. Читаю книги, решаю примеры из книг и на сайте sql-ex, но столкнулся с тем что уже много месяцев могу писать лишь запросы одного уровня сложность, не смотря на то что продолжаю обучение, такое ощущение что развитие в написании запросов остановилось. причем смотря ответы, прекрасно понимаю где какой подзапрос и для чего он нужен, но самому логически составить из более мелких компонентов общую картину затруднительно. Кто что может подсказать?
Ответ: Romanov-krd,

займитесь оптимизацией, вопросом не "как мне написать сложный запрос", а "можно ли ускорить мой простой"

сложные не так часто требуются, а вопросы оптимизации - всегда
Вопрос: Помощь нужна в написании запроса

Застрял на попытках написания запроса, условия такие: есть три таблицы 1)System, например:
System
ID Sys_Name
1 Имясистемы1
2 Имя системы2

2) Message, в которой содержатся сообщения, отправляемые системой
Ключ: System.id = Message.sysId
Message
Id SysId Message
1 1 Тест
2 1 Тест1
3 2 Тест2
4 3 Тест3

3) Dictoinary, в которой каждой системе соответствует код справочника
Ключ: System.Id = Dictionary.SysId

Dictionary
Id SysId Code
11 1 SYSTEM_OUT
1 2 SYSTEM_IN
2 3 ТЕЕ
15 4 УЕУ

Нужно зная 2 кода систем - SYSTEM_OUT и SYSTEM_IN– написать SQL запрос, который выведет имена указанных систем и количество сообщений, переданных каждой системой.

Sys_Name Количество сообщений через что тут их вывести, через обед некие?
Ответ: JOIN + GROUP BY + COUNT()
Вопрос: Написание запроса для выборки ФИО всех сотрудников, которые не пришли на работу

Здравствуйте, есть задача написать запрос. Условие таково (Необходимо написать запрос для выборки ФИО всех сотрудников, которые не пришли на работу 01.03.2011). У меня есть две таблицы (картинки прикрепил), так же имеется написанный sql запрос (картинку прикрепил). Но он не работает, постоянно выскакивает ошибка синтаксиса. Просьба помочь знающих людей! Заранее благодарю.
Ответ:
Сообщение от Андрей Поляков
WHERE Время = #2011/03/01#
Если я правильно понимаю, поле Время кроме даты содержит еще и время, т.е. имеет дробную часть. Фиксрованная же дата (к примеру, #03/01/2011#) дробной части НЕ содержит. Поэтому результат сравнения такого, как привели вы, почти всегда будет Ложь (разве что сотрудник пришел на работу ровно в полночь).

Вам привели способ избавиться от дробной части даты:

Сообщение от mobile
datevalue(Журнал.Время)
и способ сравнивать не значение даты, а ее написание

Сообщение от alvk
format(Время, "YYYYMMDD")
Вопрос: Нужна помощь в написании запроса, выборка.

Добрый день, уважаемые знатоки. Нужна Ваша помощь, в написании sql запроса.
Суть такая:
Есть таблица tablename в ней есть поле phone. В 'phone' записываются номера телефонов, но т.к. записи делают сами пользователи, с сайта, а на сайте нет проверки. Номера приходят в разных форматах:
+79991234567
999123456 7
8-999-1-2-3-4-5-6-7
+7(999)1234567
+7 999 12 34 567
8-999-123-45-67
В общем, кто на что горазд и какой смекалкой обладает.
Нужен запрос, который бы по последним символам номера (последние 4 символа) сделал выборку номеров. Не учитывая '-', ' ' и т.д.
Запрос составлял используя LIKE (%4567), но он возвращает не всю выборку.
Как быть?:)
Ответ:
Akina
wkwk
не совсем понятно как делать замену первых символов в номере (например с '7' на '8').

Гораздо разумнее приводить местные префиксы к международным, т.е. заменять ведущую '8' на '+7'. Плюс советую сохранить - один байт рук не оборвёт, а использовать данные без дополнительных преобразований намного проще.


Так-то оно так, но телефония настроена на префикс 8, т.е. не важно как номер набирать и в каком формате (при исходящей компании), преобразуется все к '8' )
Вопрос: Запросы SQL по заданию

Все доброе времени суток. Необходима помощь в написании запросов на SQL. Без году недели знаю его, поэтому возникает большое количество трудностей.
1. Создать запрос, выводящий 3 статьи, по которым наиболее часто квалифицировались в течении месяца(Статья, Количество дел). Список отсортировать по увеличению номера статьи.
2. Создать запрос, выводящий кадровый состав по званиям(Звание, Количество сотрудников).
MySQL
1
2
3
4
5
6
7
8
9
10
SELECT
  Zvanie.Name_Of_Zvanie AS Zvanie,
  COUNT(Sotrudnik.ID_Sotrudnika) AS `Kolichestvo sotrudnikov`
FROM Sotrudnik
  INNER JOIN Zvanie
    ON Sotrudnik.ID_Zvaniy = Zvanie.ID_Zvaniy
GROUP BY Sotrudnik.ID_Zvaniy,
         Zvanie.ID_Zvaniy,
         Zvanie.Name_Of_Zvanie
ORDER BY Zvanie
3.Создать запрос, который выводит информацию о сотруднике, который раскрыл наибольшее количество преступлений(ФИО,Адрес, Дата рождения, Имя звания).
Буду очень признателен за любую подсказку или пример
Ответ: IamMorgan,
2 - Создать запрос, выводящий кадровый состав по званиям (Звание, Количество сотрудников):
SQL
1
SELECT COUNT(q.ID_Sotrudnika), w.Name_Of_Zvanie FROM Sotrudnik q JOIN Zvanie w ON q.ID_Zvaniy=w.ID_Zvaniy GROUP BY w.Name_Of_Zvanie
1 - Не понятно по каким ключам связаны таблицы.
3 - Тоже не понятно как связаны таблицы (ключи) и потом, у тебя связь один к многим? Т.е. преступление может быть раскрыто только 1-м сотрудником, а не несколькими???
Вопрос: Запрос = Рекурсия + parent + подсчёт подгрупп

Уважаемые прошу помощи в написании запроса.
Нужно решить туже самую задачу как, только на tsql.
Подсчёт кол-ва элементов в текущей группе и всех подгруппах. Корневых элементов может быть несколько, для них parent_id=NULL.

Мой нерабочий запрос :(
;WITH result_table as (
	   select gg.group_id, g.parent_id, count(*) as cnt, count(*) as summ from group2good gg
	   join good_groups g on g.group_id=gg.group_id
	   WHERE g.parent_id is null
	   GROUP BY gg.group_id, g.parent_id
			UNION ALL
	   select gg.group_id, g.parent_id, count(*) as cnt, 
				(select sum(cnt) from 
				 (select count(*) as cnt from group2good gg1
				 join good_groups g1 on g1.group_id=gg1.group_id
				 WHERE g.parent_id = gg1.group_id) s) + count(*) as summ 
	   from group2good gg
	   join good_groups g on g.group_id=gg.group_id, result_table
	   WHERE result_table.parent_id = gg.group_id
	   GROUP BY gg.group_id, g.parent_id
)
select group_id, parent_id, summ from result_table rt1
Ответ:
mini.weblab
ну это учебный пример
Кому нужен пример, который не учит ничему хорошему?

mini.weblab
можете прокомментировать основные слабые места?
Первое и основное - неверный выбор способа решения задачи. Результат достигается одним запросом без циклов и табличных переменных:
CREATE FUNCTION dbo.fnGetReports
       (@EmployeeID AS int)
RETURNS TABLE
AS
RETURN (
 WITH t AS
 (
   SELECT EmployeeID, ManagerID 
   FROM HumanResources.Employee2
   WHERE EmployeeID = @EmployeeID

   UNION ALL

   SELECT EmployeeID, ManagerID 
   FROM t JOIN
    HumanResources.Employee2 e ON ManagerID = t.EmployeeID
 )
 SELECT EmployeeID, ManagerID FROM t
);

Далее: многооператорных табличных функций следует избегать. Хотя бы потому, что манипуляции с результирующей табличной переменной журналируются в журнале транзакций tempdb.
Вот вам пример с рекурсивной многооператорной функцией, - можете сами посмотреть, что происходит:
+
use tempdb;
go

create function dbo.fn1(@v int)
returns @r table (v int)
as
begin
 insert into @r values (@v);
 
 if @v > 0
  insert into @r select v from dbo.fn1(@v - 1);

 return;
end;
go

begin tran;

declare @tid nvarchar(30), @lsn nvarchar(30) = (select max([Current LSN]) from tempdb.sys.fn_dblog(null, null));

select * from dbo.fn1(3);

create table #t (tid nvarchar(30));

insert into #t
select [Transaction ID] from sys.fn_dblog(null, null) where [Current LSN] > @lsn and SPID = @@spid and [Transaction Name] = N'TVQuery';
select l.* from #t t join sys.fn_dblog(null, null) l on l.[Transaction ID] = t.tid;

rollback;
go

drop function dbo.fn1;
go
Вопрос: Запрос на "любимого" автора

Доброго времени суток. Помогите пожалуйста найти ошибку в написании запроса. Схема БД прикреплена. Нужно для каждого читателя найти любимого автора. Вот что у меня есть:
Oracle 11 SQL
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
SELECT a.id_читателя, 
читатели.фамилия+' '+читатели.имя+' '+читатели.отчество AS chitatel,
a.id_автора, 
авторы.фамилия+' '+авторы.имя+' '+авторы.отчество AS avtor,
MAX(kolvo_knig) AS max_kolvo
FROM
(SELECT заказ_читателя.id_читателя, авторы_книг.id_автора, 
COUNT(авторы_книг.id_книги) AS kolvo_knig
FROM ЗАКАЗ_ЧИТ заказ_читателя,
заказ,
книги,
авторы_книг
WHERE заказ_читателя.id_заказа=заказ.id_заказа
AND заказ.id_книги=книги.id_книги
AND книги.id_книги=авторы_книг.id_книги
GROUP BY заказ_читателя.id_читателя, авторы_книг.id_автора
) a,
авторы, читатели
WHERE TO_NUMBER(a.id_автора)=авторы.id_автора --and a.id_читателя=читатели.id_читателя
GROUP BY a.id_читателя, читатели.фамилия+' '+читатели.имя+' '+читатели.отчество, a.id_автора, авторы.фамилия+' '+авторы.имя+' '+авторы.отчество;
Ответ: ОГРОМНЕЙШЕЕ спасибо! все отлично работает! подзамотал перед сном)))) еще раз спасибо. Если у Вас будет завтра желание и время, гляньте мой еще один запрос по этой же схеме, последний остался, уже 2 месяца мучаюсь. Он там короткий, называется темв Запрос на подсчет изданий
Вопрос: прошу помощи в написании запроса

здравствуйте. прошу помочь написать запрос:
К таблице ОРГАНИЗАЦИИ добавить столбцы: Дистрибьюторы, Фамилия, КонтактныйТел (формат: ###-###-####), Категория (значения: A, B, C, D). На одну организацию могут работать несколько Дистрибьюторов, один дистрибьютор может работать только на одну Организацию. Дистрибьюторов назначить на те организации, у которых заказов на сумму более NN руб.

особенный затык с заданием шаблона ввода. не могу найти нигде какой оператор использовать((

Спасибо
Ответ:
Glory
alex-zaitsev
может вместо нижних подчеркиваний больше подойдет '#'?

Вместо # подойдет чтение в хелпе про LIKE

ну может у них телефон ####-####-#### :))
Вопрос: Пожалуйста помогите с написанием запроса

Здравствуйте. Помогите пожалуйста с одним запросом. На рисунке приводятся четыре столбца: Number, Log, Date, User.
Мне нужно из таблицы выбрать все неповторяющиеся логи, основываясь по номеру и пользователю. Как условие для одинаковых логов выбрать самые ранние.

Справа на рисунке указан результат который мне требуется.

Премного благодарен вам за помощь!

К сообщению приложен файл. Размер - 43Kb
Ответ:
Akina
SELECT Number, Log, Min(Date) AS Date, User
FROM Table
GROUP BY Number, Log, User


Огромное спасибо!