Форум программистов, компьютерный форум, киберфорум
Microsoft SQL Server
Войти
Регистрация
Восстановить пароль
Блоги Сообщество Поиск Заказать работу  
 
Рейтинг 4.50/6: Рейтинг темы: голосов - 6, средняя оценка - 4.50
 Аватар для KatyaP
1 / 1 / 0
Регистрация: 13.12.2012
Сообщений: 43

Выборка специалистов из данной базы данных

09.12.2014, 00:43. Показов 1326. Ответов 7
Метки нет (Все метки)

Студворк — интернет-сервис помощи студентам
Здравствуйте
В БД имеются следующие таблицы:

Врач:
id - Primary Key
ФИО
Специальность

График приема:
id - Primary Key
День недели - varchar
Время начала приема - time

Запись: (Запись пациента ко врачу)
id - Primary Key
Дата - date
Время
id_Врача
Пациент

Известно, что каждый врач работает в день по 3 часа и принимает каждого пациента 20 минут

Необходимо сделать следующую выборку.
Пациент может пройти медосмотр во вторник с 14 до 16 часов. Выбрать всех специалистов, к которым он может попасть.
0
Лучшие ответы (1)
Programming
Эксперт
39485 / 9562 / 3019
Регистрация: 12.04.2006
Сообщений: 41,671
Блог
09.12.2014, 00:43
Ответы с готовыми решениями:

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

Выборка записей случайным образом из базы данных
Необходимо разработать программу в которой,понятия могут выбираться из заранее заданного множества случайным образом. Формирование БД...

Выборка из базы данных
большая просьба есть база сделанная в ацесе . форму создал , привязал к ней таблицу все выбирается . А как сделать кнопку что бы она...

7
19 / 19 / 12
Регистрация: 09.12.2014
Сообщений: 250
10.12.2014, 10:34
График приема:
id - Primary Key
День недели - varchar
Время начала приема - time

я не вижу здесь привязки к врачу, или у вас 100+ врачей и все работают в одно и то же время, по 3 часа?
1
 Аватар для KatyaP
1 / 1 / 0
Регистрация: 13.12.2012
Сообщений: 43
10.12.2014, 21:19  [ТС]
Извините, забыла для этой таблицы указать поле: id_Врача
0
19 / 19 / 12
Регистрация: 09.12.2014
Сообщений: 250
11.12.2014, 13:21
исходные данные: mssql прекрасно понимает формат datatime так что пациент может придти
с datatimeP = вторник 14ч до datatimeP+2:00= вторник 16ч
алгоритм: сразу выбираем только тех врачей, кто работает во вторник "график приёма.День недели=вторник"
так что врач теперь работает с datatimeV по datatimeV+3:00
Далее работаем со временем, имеем
если datatimeP>datatimeV+3:00 или datatimeP+2<datatimeV тогда врач не может принять, иначе
если datatimeP>datatimeV
тогда если datatimeP+2>datatimeV+3 тогда исследуем период between datatimeP and datatimeV+3 иначе
исследуем период between datatimeP and datatimeP+2 КОНЕЦ
иначе исследуем период between datatimeV and datatimeP+2

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

такой сложный запрос писать без возможности проверки (могу потерять 1 запись на операциях сравнения) не хочется.
1
1313 / 945 / 144
Регистрация: 17.01.2013
Сообщений: 2,348
11.12.2014, 18:29
Лучший ответ Сообщение было отмечено KatyaP как решение

Решение

KatyaP, сегодня заняться особо нечем было, - ловите)
Кликните здесь для просмотра всего текста

T-SQL
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
IF OBJECT_ID('Специальности') IS NULL
BEGIN
  CREATE TABLE Специальности (
            id       INT PRIMARY KEY
          , Название VARCHAR(100));
  INSERT Специальности (ID, Название) VALUES 
    (1, 'Терапевт'), (2, 'Окулист'), (3, 'Невролог'), (4, 'Логопед'), (5, 'Хирург');
END;
 
IF OBJECT_ID('Врачи') IS NULL
BEGIN
  CREATE TABLE Врачи (
            id           INT PRIMARY KEY
          , ФИО          VARCHAR(100)
          , Спец         INT FOREIGN KEY REFERENCES Специальности(id)
          , Длительность INT);
 
  INSERT Врачи (ID, ФИО, Спец, Длительность) VALUES 
    (1, 'Врач01', 1, 20), (2, 'Врач02', 1, 20), (3, 'Врач03', 1, 40), (4, 'Врач04', 1, 20), 
    (5, 'Врач05', 2, 20), (6, 'Врач06', 2, 20), (7, 'Врач07', 3, 20), (8, 'Врач08', 3, 20), 
    (9, 'Врач09', 4, 20), (10, 'Врач10', 5, 20), (11, 'Врач11', 5, 20);
END;
 
IF OBJECT_ID('График') IS NULL
BEGIN
  CREATE TABLE График (
            id           INT IDENTITY UNIQUE NOT NULL 
          , врач         INT FOREIGN KEY REFERENCES Врачи(id)
          , ДеньНедели   INT
          , НачалоПриема TIME
          , КонецПриема  TIME
          , PRIMARY KEY (Врач, ДеньНедели)
      );
  INSERT График (врач, ДеньНедели, НачалоПриема, КонецПриема) VALUES 
    ( 1, 2, '09:00', '16:00'), ( 2, 2, '13:00', '20:00'), ( 3, 2, '11:00', '18:00'), 
    ( 4, 2, '11:00', '18:00'), ( 5, 2, '13:00', '20:00'), ( 6, 2, '09:00', '16:00'), 
    ( 7, 2, '10:00', '15:00'), ( 8, 2, '14:00', '19:00'), ( 9, 2, '15:00', '20:00'), 
    (10, 2, '09:00', '15:00'), (11, 2, '14:00', '20:00');
END;
 
IF OBJECT_ID('Запись') IS NULL
BEGIN
  CREATE TABLE Запись (
            id      INT IDENTITY UNIQUE NOT NULL 
          , врач    INT FOREIGN KEY REFERENCES Врачи(id)
          , время   DATETIME
          , пациент INT -- FOREIGN KEY REFERENCES Пациенты(id)
          , PRIMARY KEY (время, врач)
      );
 
  INSERT Запись (врач, время, пациент) VALUES 
    ( 1, '20141209 09:00',  1), ( 1, '20141209 09:20',  2), ( 1, '20141209 10:20',  3), ( 1, '20141209 12:40',  4), 
    ( 1, '20141209 13:40',  5), ( 1, '20141209 14:00',  6), ( 1, '20141209 15:00',  7), ( 1, '20141209 15:20',  8), 
    ( 2, '20141209 15:20',  9), ( 2, '20141209 15:40', 10), ( 2, '20141209 16:00', 11), ( 2, '20141209 14:00', 12), 
    ( 2, '20141209 14:20', 13), ( 2, '20141209 14:40', 14), ( 2, '20141209 15:00', 15), ( 3, '20141209 14:00', 16), 
    ( 3, '20141209 14:20', 17), ( 3, '20141209 14:40', 18), ( 3, '20141209 15:00', 19), ( 3, '20141209 15:20', 20), 
    ( 3, '20141209 15:40', 21), ( 4, '20141209 14:00', 22), ( 4, '20141209 14:20', 23), ( 4, '20141209 14:40', 24), 
    ( 4, '20141209 15:00', 25), ( 4, '20141209 15:20', 26), ( 4, '20141209 15:40', 27), ( 4, '20141209 16:00', 28),
    ( 5, '20141209 13:40', 29), ( 5, '20141209 14:00', 30), ( 5, '20141209 14:20', 31), ( 5, '20141209 14:40', 32), 
    ( 5, '20141209 15:00', 33), ( 5, '20141209 15:20', 34), ( 6, '20141209 14:00', 35), ( 6, '20141209 14:20', 36), 
    ( 6, '20141209 14:40', 37), ( 6, '20141209 15:00', 38), ( 6, '20141209 15:20', 39), ( 6, '20141209 15:40', 40), 
    ( 7, '20141209 14:00', 41), ( 7, '20141209 14:20', 42), ( 7, '20141209 14:40', 43), ( 8, '20141209 14:20', 44),
    ( 8, '20141209 14:40', 45), ( 8, '20141209 15:00', 46), ( 8, '20141209 15:20', 47), ( 8, '20141209 15:40', 48), 
    ( 9, '20141209 15:20', 49), (10, '20141209 14:20', 50), (10, '20141209 14:40', 51), (11, '20141209 14:00', 52), 
    (11, '20141209 15:00', 53), (11, '20141209 15:20', 54), (11, '20141209 15:40', 55), (11, '20141209 16:00', 56);
END;
GO
T-SQL
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
DECLARE @from TIME = '14:00', @to TIME = '16:00'
IF OBJECT_ID('tempdb..#СвободноеВремя') IS NOT NULL DROP TABLE #СвободноеВремя
 
SELECT
    DENSE_RANK() OVER (ORDER BY v.Спец) npp
  , v.Спец, s.Название Специалист, g.врач, v.ФИО
  , g.ДеньНедели, t_free время
INTO #СвободноеВремя
FROM Врачи v
JOIN Специальности s ON s.id = v.Спец
JOIN График g ON g.врач = v.id AND g.ДеньНедели = 2 
CROSS APPLY ( SELECT
    t_from = iif(g.НачалоПриема > @from, g.НачалоПриема, @from)
  , t_to   = iif(g.КонецПриема  < @to,   g.КонецПриема,  @to)
  ) t
JOIN master..spt_values n ON n.type = 'P' 
  AND n.number < DATEDIFF(MINUTE, t_from, t_to) / v.Длительность
CROSS APPLY ( SELECT
  t_free = DATEADD(MINUTE, n.number * v.Длительность, t_from)
  ) t2
WHERE NOT EXISTS (
    SELECT *
    FROM Запись z
    WHERE z.врач = v.id AND DATEPART(WEEKDAY, z.время) = g.ДеньНедели 
      AND convert(TIME, z.время) = t_free
    );
 
SELECT * FROM #СвободноеВремя;
nppСпецСпециалистврачФИОДеньНеделивремя
11Терапевт1Врач01214:20:00.000
11Терапевт1Врач01214:40:00.000
11Терапевт1Врач01215:40:00.000
22Окулист5Врач05215:40:00.000
33Невролог8Врач08214:00:00.000
44Логопед9Врач09215:00:00.000
44Логопед9Врач09215:40:00.000
55Хирург10Врач10214:00:00.000
55Хирург11Врач11214:20:00.000
55Хирург11Врач11214:40:00.000
T-SQL
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
;WITH ПоискВариантов AS (
  SELECT TOP (1) WITH TIES 
    1 iter, f.Спец id, 
    convert(NVARCHAR(max), CONCAT (',', f.Спец, ',')) Спец, 
    convert(NVARCHAR(max), CONCAT (',', f.врач, ',')) Врач, 
    convert(NVARCHAR(max), CONCAT (',', left(f.время, 5), ',')) Время
  FROM #СвободноеВремя f
  ORDER BY f.Спец
  
  UNION ALL
  
  SELECT
    r.iter + 1, f.Спец, 
    CONCAT (r.Спец, f.Спец, ',') Спец, 
    CONCAT (r.Врач, f.врач, ',') Врач, 
    CONCAT (r.Время, left(f.время, 5) + ',') Время
  FROM ПоискВариантов r
  JOIN #СвободноеВремя f ON f.Спец > r.id
  WHERE r.Время NOT LIKE CONCAT ('%,', left(f.время, 5), ',%') 
    AND r.Спец NOT LIKE CONCAT ('%,', f.Спец, ',%')
  )
, Rezult AS (
  SELECT TOP (1) WITH TIES 
      row_number() OVER (ORDER BY r.iter DESC) Npp, 
      STUFF(r.Врач, 1, 1, '') Врач, 
      STUFF(r.Время, 1, 1, '') Время
    FROM ПоискВариантов r
    ORDER BY r.iter DESC
  )
, ПланПосещений AS (
  SELECT
      r.Npp, 1 step, s.Название, v.ФИО, CONVERT(TIME, LEFT(r.Время, pt - 1)) Время, 
      STUFF(r.Врач, 1, pv, '') rv, STUFF(r.Время, 1, pt, '') rt
    FROM Rezult r
    CROSS APPLY (SELECT
      CHARINDEX(',', r.Врач) pv, 
      CHARINDEX(',', r.Время) pt
      ) p
    JOIN Врачи v ON v.id = left(r.Врач, pv - 1)
    JOIN Специальности s ON s.id = v.Спец
 
  UNION ALL
 
  SELECT
      r.Npp, 1 + step, s.Название, v.ФИО, CONVERT(TIME, LEFT(r.rt, pt - 1)) Время, 
      STUFF(r.rv, 1, pv, '') rv, STUFF(r.rt, 1, pt, '') rt
    FROM ПланПосещений r
    CROSS APPLY ( SELECT
      CHARINDEX(',', r.rv) pv, 
      CHARINDEX(',', r.rt) pt
      ) p
    JOIN Врачи v ON v.id = left(r.rv, pv - 1)
    JOIN Специальности s ON s.id = v.Спец
    WHERE pv > 0
  )
SELECT r.Npp Вариант, r.Время, r.Название, r.ФИО
FROM ПланПосещений r
ORDER BY r.Npp, r.Время;
ВариантВремяНазваниеФИО
114:00:00.000НеврологВрач08
114:20:00.000ХирургВрач11
114:40:00.000ТерапевтВрач01
115:00:00.000ЛогопедВрач09
115:40:00.000ОкулистВрач05
214:00:00.000НеврологВрач08
214:20:00.000ТерапевтВрач01
214:40:00.000ХирургВрач11
215:00:00.000ЛогопедВрач09
215:40:00.000ОкулистВрач05
1
 Аватар для KatyaP
1 / 1 / 0
Регистрация: 13.12.2012
Сообщений: 43
12.12.2014, 00:13  [ТС]
Спасибо! буду разбираться)
0
 Аватар для KatyaP
1 / 1 / 0
Регистрация: 13.12.2012
Сообщений: 43
17.12.2014, 01:15  [ТС]
честно говоря так и не удалось разобраться(((
0
1313 / 945 / 144
Регистрация: 17.01.2013
Сообщений: 2,348
17.12.2014, 18:07
Почитайте про рекурсивные CTE
Например, вот тут
Или еще где-нибудь, по поиску

Добавлено через 3 минуты
Или вот, от MS: Рекурсивные запросы, использующие обобщенные табличные выражения

Добавлено через 10 часов 5 минут
Вариант немного попроще:
T-SQL
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
;with Поиск as (
  select top(1) with ties 
      ПосетитьВрачей=1, 
      t.время, 
      Спец=convert(varchar(max),concat(',',t.Спец,',')), 
      ГрафикОбследований=convert(varchar(max),
        concat(left(t.время,5),':',t.ФИО,' (',t.Специалист,')'))
    from #СвободноеВремя t
    order by t.время
  union all
  select
      ПосетитьВрачей+1, 
      t.время, 
      convert(varchar(max),concat(p.Спец,t.Спец,',')), 
      convert(varchar(max),
        concat(p.ГрафикОбследований, '; ', left(t.время,5),':',t.ФИО,' (',t.Специалист,')'))
    from Поиск p
    join #СвободноеВремя t on t.время>p.время 
      and p.Спец not like concat('%,',t.Спец,',%') -- не дублировать специалистов при выборе
  )
select top(3) with ties
  row_number()over(order by ПосетитьВрачей desc)Вариант, 
  ПосетитьВрачей, 
  ГрафикОбследований
from Поиск
order by ПосетитьВрачей desc
ВариантПосетитьВрачейГрафикОбследований
1514:00:Врач08 (Невролог); 14:20:Врач11 (Хирург); 14:40:Врач01 (Терапевт); 15:00:Врач09 (Логопед); 15:40:Врач05 (Окулист)
2514:00:Врач08 (Невролог); 14:20:Врач01 (Терапевт); 14:40:Врач11 (Хирург); 15:00:Врач09 (Логопед); 15:40:Врач05 (Окулист)
3414:00:Врач08 (Невролог); 14:20:Врач01 (Терапевт); 15:00:Врач09 (Логопед); 15:40:Врач05 (Окулист)
4414:00:Врач08 (Невролог); 14:20:Врач01 (Терапевт); 14:40:Врач11 (Хирург); 15:40:Врач05 (Окулист)
5414:00:Врач08 (Невролог); 14:20:Врач01 (Терапевт); 14:40:Врач11 (Хирург); 15:00:Врач09 (Логопед)
6414:00:Врач08 (Невролог); 14:20:Врач01 (Терапевт); 14:40:Врач11 (Хирург); 15:40:Врач09 (Логопед)
7414:00:Врач08 (Невролог); 14:40:Врач01 (Терапевт); 15:00:Врач09 (Логопед); 15:40:Врач05 (Окулист)
8414:00:Врач10 (Хирург); 14:20:Врач01 (Терапевт); 15:00:Врач09 (Логопед); 15:40:Врач05 (Окулист)
9414:00:Врач10 (Хирург); 14:40:Врач01 (Терапевт); 15:00:Врач09 (Логопед); 15:40:Врач05 (Окулист)
10414:00:Врач08 (Невролог); 14:40:Врач11 (Хирург); 15:00:Врач09 (Логопед); 15:40:Врач01 (Терапевт)
11414:00:Врач08 (Невролог); 14:40:Врач11 (Хирург); 15:00:Врач09 (Логопед); 15:40:Врач05 (Окулист)
12414:00:Врач08 (Невролог); 14:20:Врач11 (Хирург); 15:00:Врач09 (Логопед); 15:40:Врач01 (Терапевт)
13414:00:Врач08 (Невролог); 14:20:Врач11 (Хирург); 15:00:Врач09 (Логопед); 15:40:Врач05 (Окулист)
14414:00:Врач08 (Невролог); 14:20:Врач11 (Хирург); 14:40:Врач01 (Терапевт); 15:40:Врач05 (Окулист)
15414:00:Врач08 (Невролог); 14:20:Врач11 (Хирург); 14:40:Врач01 (Терапевт); 15:00:Врач09 (Логопед)
16414:00:Врач08 (Невролог); 14:20:Врач11 (Хирург); 14:40:Врач01 (Терапевт); 15:40:Врач09 (Логопед)
0
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
inter-admin
Эксперт
29715 / 6470 / 2152
Регистрация: 06.03.2009
Сообщений: 28,500
Блог
17.12.2014, 18:07
Помогаю со студенческими работами здесь

Выборка из базы данных
здравствуйте!!! Помогите разобраться с проблемой выборки из базы данных... &lt;? if(!isset($id)) { $result = mysql_query...

Выборка данных из базы
Привет всем Для начала напишу то, что реализовано. В программе реализован выбор по трём полям. Если есть совпадение, то выводится...

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

Выборка из базы данных
private function select($table_name, $fields, $where = &quot;&quot;, $order = &quot;&quot;, $up = true, $limit = &quot;&quot;) { for ($i = 0; $i &lt; count($fields);...

Выборка из базы данных
При выборке из базы данных данной функцией. public function getAll($table_name, $order, $up) { return...


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
8
Ответ Создать тему
Новые блоги и статьи
Первый деплой
lagorue 16.01.2026
Не спеша развернул своё 1ое приложение в kubernetes. А дальше мне интересно создать 1фронтэнд приложения и 2 бэкэнд приложения развернуть 2 деплоя в кубере получится 2 сервиса и что-бы они. . .
Расчёт переходных процессов в цепи постоянного тока
igorrr37 16.01.2026
/ * Дана цепь постоянного тока с R, L, C, k(ключ), U, E, J. Программа составляет систему уравнений по 1 и 2 законам Кирхгофа, решает её и находит токи на L и напряжения на C в установ. режимах до и. . .
Восстановить юзерскрипты Greasemonkey из бэкапа браузера
damix 15.01.2026
Если восстановить из бэкапа профиль Firefox после переустановки винды, то список юзерскриптов в Greasemonkey будет пустым. Но восстановить их можно так. Для этого понадобится консольная утилита. . .
Изучаю kubernetes
lagorue 13.01.2026
А пригодятся-ли мне знания kubernetes в России?
Сукцессия микоризы: основная теория в виде двух уравнений.
anaschu 11.01.2026
https:/ / rutube. ru/ video/ 7a537f578d808e67a3c6fd818a44a5c4/
WordPad для Windows 11
Jel 10.01.2026
WordPad для Windows 11 — это приложение, которое восстанавливает классический текстовый редактор WordPad в операционной системе Windows 11. После того как Microsoft исключила WordPad из. . .
Classic Notepad for Windows 11
Jel 10.01.2026
Old Classic Notepad for Windows 11 Приложение для Windows 11, позволяющее пользователям вернуть классическую версию текстового редактора «Блокнот» из Windows 10. Программа предоставляет более. . .
Почему дизайн решает?
Neotwalker 09.01.2026
В современном мире, где конкуренция за внимание потребителя достигла пика, дизайн становится мощным инструментом для успеха бренда. Это не просто красивый внешний вид продукта или сайта — это. . .
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2026, CyberForum.ru