SquirrelInBox

ind

Nov 24th, 2015
896
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
SQL 18.27 KB | None | 0 0
  1. /*
  2.     Задача 2. База данных ≪Городская Дума≫.
  3. В базе хранятся имена, адреса, домашние и служебные телефоны
  4. всех членов Думы. В Думе работает порядка сорока комиссий,
  5. все участники которых являются членами Думы. Каждая комиссия
  6. имеет свой профиль, например, вопросы образования, проблемы,
  7. связанные с жильем, и так далее. Данные по каждой из комиссий включают:
  8. председатель и состав, прежние (за 10 предыдущих лет) председатели
  9. и члены этой комиссии, даты включения и выхода из состава комиссии,
  10. избрания ее председателей. Члены Думы могут заседать в нескольких
  11. комиссиях. В базу заносятся время и место проведения каждого
  12. заседания комиссии с указанием депутатов и служащих Думы, которые
  13. участвуют в его организации. Создать триггер для проверки того, что
  14. один и тот же депутат в одно время не заседает в двух комиссиях.
  15. 1) Показать список комиссий, для каждой – ее состав и председателя.
  16. 2) Для введенного пользователем интервала дат и названия комиссии
  17.     показать в хронологическом порядке всех ее председателей.
  18. 3) Показать список членов Думы, для каждого из них – список комиссий,
  19.     в которых он участвовал и/или был председателем.
  20. 4) Для указанного интервала дат и комиссии выдать список членов
  21.     с указанием количества пропущенных заседаний.
  22. 5) Вывести список заседаний в указанный интервал дат в хронологическом
  23.     порядке, для каждого заседания – список присутствующих.
  24. 6) По каждой комиссии показать количество проведенных заседаний
  25.     в указанный период времени.
  26. */
  27.  
  28. USE master
  29. GO
  30.  
  31. IF  EXISTS (
  32.         SELECT name
  33.                 FROM sys.DATABASES
  34.                 WHERE name = N'ElenaBeklenishcheva'
  35. )
  36. ALTER DATABASE ElenaBeklenishcheva SET single_user WITH ROLLBACK immediate
  37. GO
  38.  
  39. IF  EXISTS (
  40.         SELECT name
  41.                 FROM sys.DATABASES
  42.                 WHERE name = N'ElenaBeklenishcheva'
  43. )
  44. DROP DATABASE [ElenaBeklenishcheva]
  45. GO
  46.  
  47. CREATE DATABASE [ElenaBeklenishcheva]
  48. GO
  49.  
  50. USE [ElenaBeklenishcheva]
  51. GO
  52.  
  53. IF EXISTS(
  54.   SELECT *
  55.     FROM sys.schemas
  56.    WHERE name = N'Scheme'
  57. )
  58.  DROP SCHEMA Scheme
  59. GO
  60.  
  61. CREATE SCHEMA Scheme
  62. GO
  63.  
  64.  
  65. IF OBJECT_ID('units', 'U') IS NOT NULL
  66.   DROP TABLE units
  67. GO
  68.  
  69.  
  70. --персональные данные
  71. CREATE TABLE units (
  72.     id INT PRIMARY KEY NOT NULL,
  73.     surname VARCHAR(50) NOT NULL,
  74.     name VARCHAR(50) NOT NULL,
  75.     patronymic VARCHAR(50) NOT NULL,
  76.     city VARCHAR(50) NOT NULL,
  77.     street VARCHAR(50) NOT NULL,
  78.     house INT NOT NULL,
  79.     flat INT,
  80.     personal_number BIGINT,
  81.     home_number BIGINT
  82. )
  83. GO
  84.  
  85. --корректность номеров
  86. ALTER TABLE units
  87. ADD CONSTRAINT CHK_units CHECK (
  88.     personal_number >= 9000000000 AND
  89.     personal_number <= 9999999999 AND
  90.     home_number > 9999
  91. )
  92. GO
  93.  
  94. INSERT INTO units VALUES
  95. (1, 'Абрамов', 'Августин', 'Алексеевич', 'Екатеринбург', 'Ленина', 45, 5, 9012345678, NULL),
  96. (2, 'Авдеев', 'Андрей', 'Антонович', 'Екатеринбург', 'Малышева', 1, 2, 9014569885, NULL),
  97. (3, 'Агафонов', 'Константин', 'Кириллович', 'Богданович', 'Мира', 2, 3, NULL, 83439342793),
  98. (4, 'Андреев', 'Дмитрий', 'Александрович', 'Хабаровск', 'Советская', 21, 13, 9051235660, 83432342793),
  99. (5, 'Алексеев', 'Василий', 'Иванович', 'Новосибирск', 'Прокопьева', 115, 23, 9051235662, NULL),
  100. (6, 'Баранов','Виктор', 'Константинович', 'Краснодар', 'Алюминиевая', 21, 1, 9051235664, 83432342794),
  101. (7, 'Буров', 'Антон', 'Михайлович', 'Белореченск', 'Брянская', 212, 131, NULL, 83432342796),
  102. (8, 'Быкова', 'Анастасия', 'Андреевна', 'Ханты-мансийск', 'Мичурина', 213, 113, NULL, NULL),
  103. (9, 'Васильева', 'Екатерина', 'Васильевна', 'Екатеринбург', 'Победы', 21, 13, 9051435660, 83432342756),
  104. (10, 'Воробьева', 'Дарья', 'Андреевна', 'Ревда', 'Гагарина', 219, 3, 9051234560, 83432395793),
  105. (11, 'Власова', 'Ольга', 'Андреевна', 'Каменск-Уральский', 'Шестакова', 21, 13, 9051245660, NULL)
  106. GO
  107.  
  108.  
  109. IF OBJECT_ID('committee', 'U') IS NOT NULL
  110.     DROP TABLE committee
  111. GO
  112. --существующие коммиссии
  113. CREATE TABLE committee (
  114.     id INT PRIMARY KEY NOT NULL,
  115.     questions VARCHAR(100) NOT NULL
  116. )
  117. GO
  118.  
  119. INSERT INTO committee VALUES
  120. (1, 'Аграрные вопросы'),
  121. (2, 'Бюджет и налоги'),
  122. (3, 'Общественные вопросы'),
  123. (4, 'Культура'),
  124. (5, 'Жилищная политика'),
  125. (6, 'Оборона'),
  126. (7, 'Медицина')
  127. GO
  128.  
  129.  
  130. IF OBJECT_ID('structure', 'U') IS NOT NULL
  131.     DROP TABLE STRUCTURE
  132. GO
  133. --состав комиссий; 1 - был или есть предселатель
  134. CREATE TABLE STRUCTURE (
  135.     committee_id INT NOT NULL,
  136.     unit_id INT NOT NULL,
  137.     inclusion DATE NOT NULL,
  138.     expulsion DATE,
  139.     isChairman bit NOT NULL,
  140.     chairmanFirstDay DATE,
  141.     chairmanLastDay DATE
  142.  
  143.     FOREIGN KEY (committee_id) REFERENCES committee(id),
  144.     FOREIGN KEY (unit_id) REFERENCES units(id)
  145. )
  146. GO
  147.  
  148. /*INSERT INTO structure VALUES
  149. (1, 1, '20151128', '20151228', 0, null, null)
  150. GO
  151.  
  152. INSERT INTO structure VALUES
  153. (1, 2, '20151128', '20151228', 1, '20151128', null)
  154. GO
  155.  
  156. INSERT INTO structure VALUES
  157. (2, 3, '20151128', '20151228', 1, '20151201', '20151215')
  158. GO*/
  159.  
  160. --корректные даты работы в комиссии
  161. --корректные даты работы председателей
  162. ALTER TABLE STRUCTURE
  163. ADD CONSTRAINT chk_structure CHECK (
  164.     (expulsion IS NULL OR expulsion > inclusion) AND
  165.     (
  166.         isChairman = 0 AND
  167.         chairmanFirstDay IS NULL AND
  168.         chairmanLastDay IS NULL
  169.     OR
  170.         isChairman = 1 AND
  171.         NOT(chairmanFirstDay IS NULL) AND
  172.         (inclusion < chairmanFirstDay OR inclusion = chairmanFirstDay) AND
  173.         (
  174.             chairmanLastDay IS NULL OR
  175.             chairmanFirstDay < chairmanLastDay AND
  176.             (expulsion IS NULL OR expulsion >chairmanLastDay OR expulsion = chairmanLastDay)
  177.         )
  178.     )
  179. )
  180. GO
  181.  
  182. IF OBJECT_ID('trigForChairman', 'TR') IS NOT NULL
  183.     DROP TRIGGER trigForChairman
  184. GO
  185.  
  186. CREATE TRIGGER trigForChairman ON STRUCTURE FOR INSERT AS
  187. BEGIN
  188.     -- чтобы в каждый период времени был только один предеседатель
  189.     SELECT *
  190.     FROM inserted
  191.     SELECT * FROM STRUCTURE
  192.     DECLARE @counter1 INT;
  193.     DECLARE @counter2 INT;
  194.     SET @counter1 = (
  195.             SELECT COUNT(*)
  196.             FROM inserted, STRUCTURE
  197.             WHERE (
  198.                 STRUCTURE.isChairman=1 AND
  199.                 inserted.committee_id = STRUCTURE.committee_id AND
  200.                 inserted.isChairman=1 AND
  201.                 inserted.chairmanLastDay IS NULL AND
  202.                 STRUCTURE.chairmanLastDay IS NULL
  203.             )
  204.         );
  205.     SET @counter2 = (
  206.         SELECT COUNT(*)
  207.         FROM STRUCTURE, inserted
  208.         WHERE
  209.             STRUCTURE.isChairman=1 AND  
  210.             inserted.committee_id = STRUCTURE.committee_id AND
  211.             inserted.isChairman=1 AND
  212.             (
  213.                 (
  214.                     (
  215.                         STRUCTURE.chairmanFirstDay < inserted.chairmanFirstDay
  216.                         OR
  217.                         STRUCTURE.chairmanFirstDay = inserted.chairmanFirstDay
  218.                     )
  219.                     AND (
  220.                         STRUCTURE.chairmanLastDay > inserted.chairmanFirstDay
  221.                         OR
  222.                         STRUCTURE.chairmanLastDay IS NULL
  223.                     )
  224.                 ) OR (
  225.                     STRUCTURE.chairmanFirstDay > inserted.chairmanFirstDay
  226.                     OR
  227.                     STRUCTURE.chairmanFirstDay = inserted.chairmanFirstDay
  228.                 ) AND (
  229.                     STRUCTURE.chairmanFirstDay < inserted.chairmanLastDay
  230.                     OR
  231.                     STRUCTURE.chairmanLastDay < inserted.chairmanLastDay
  232.                     OR
  233.                     STRUCTURE.chairmanLastDay = inserted.chairmanLastDay
  234.                     OR inserted.chairmanLastDay IS NULL
  235.                     OR (
  236.                         STRUCTURE.chairmanLastDay IS NULL
  237.                         AND
  238.                         inserted.chairmanLastDay >STRUCTURE.chairmanFirstDay
  239.                     )
  240.                 )
  241.             )
  242.         );
  243.     print(@counter1)
  244.     print(@counter2)
  245.     IF (@counter1 > 1 OR @counter2 > 1)
  246.     BEGIN
  247.         print ('Председатель данной компании уже есть');
  248.         ROLLBACK TRANSACTION;
  249.         RETURN
  250.     END
  251. END
  252. GO
  253.  
  254. --bad examples
  255. /*INSERT INTO structure VALUES
  256. (1, 1, '20150101', '20160101', 1, '20150401', '20150425')
  257. GO*/
  258.  
  259. /*INSERT INTO structure VALUES
  260. (1, 2, '20150101', '20151231', 1, '20150201', '20150410')
  261. GO*/
  262.  
  263. /*INSERT INTO structure VALUES
  264. (1, 2, '20150101', '20151231', 1, '20150201', '20150510')
  265. GO*/
  266.  
  267. /*INSERT INTO structure VALUES
  268. (1, 2, '20150101', '20151231', 1, '20150201', null)
  269. GO*/
  270. /*INSERT INTO structure VALUES
  271. (2, 1, '20150101', '20151231', 1, '20150201', null)
  272. GO
  273.  
  274. INSERT INTO structure VALUES
  275. (1, 2, '20150101', '20151231', 1, '20150201', '20150510')
  276. GO
  277.  
  278. INSERT INTO structure VALUES
  279. (1, 2, '20150101', '20151231', 1, '20150301', '20150510')
  280. GO*/
  281.  
  282. /*INSERT INTO structure VALUES
  283. (3, 1, '20150101', '20151231', 1, '20150201', '20150510')
  284. GO
  285.  
  286. INSERT INTO structure VALUES
  287. (3, 2, '20150101', '20151231', 1, '20150301', '20150310')
  288. GO*/
  289.  
  290. /*INSERT INTO structure VALUES
  291. (4, 1, '20150101', '20151231', 1, '20150201', null)
  292. GO
  293.  
  294. INSERT INTO structure VALUES
  295. (4, 1, '20150101', '20151231', 1, '20150301', '20150401')
  296. GO
  297. */
  298. SELECT * FROM STRUCTURE
  299.  
  300.  
  301. INSERT INTO STRUCTURE VALUES
  302. (1, 11, '20000101', '20050101', 1, '20010101', '20030101')
  303. GO
  304. INSERT INTO STRUCTURE VALUES
  305. (2, 2, '20121211', NULL, 1, '20121211', NULL)
  306. GO
  307. INSERT INTO STRUCTURE VALUES
  308. (1, 1, '20110611', NULL, 1, '20110611', NULL)
  309. GO
  310. INSERT INTO STRUCTURE VALUES
  311. (3, 3, '20101010', NULL, 1, '20101025', NULL)
  312. GO
  313. INSERT INTO STRUCTURE VALUES
  314. (4, 4, '20131010', NULL, 1, '20131212', NULL)
  315. GO
  316. INSERT INTO STRUCTURE VALUES
  317. (5, 5, '20141010', NULL, 1, '20150101', NULL)
  318. GO
  319. INSERT INTO STRUCTURE VALUES
  320. (6, 6, '20151010', NULL, 0, NULL, NULL)
  321. GO
  322. INSERT INTO STRUCTURE VALUES
  323. (7, 7, '20101010', NULL, 0, NULL, NULL)
  324. GO
  325. INSERT INTO STRUCTURE VALUES
  326. (1, 8, '20110611', NULL, 0, NULL, NULL)
  327. GO
  328. INSERT INTO STRUCTURE VALUES
  329. (2, 9, '20121211', NULL, 0, NULL, NULL)
  330. GO
  331. INSERT INTO STRUCTURE VALUES
  332. (3, 10, '20101010', NULL, 0, NULL, NULL)
  333. GO
  334.  
  335. SELECT * FROM STRUCTURE
  336. GO
  337.  
  338.  
  339. IF OBJECT_ID('meeting', 'U') IS NOT NULL
  340.     DROP TABLE meeting
  341. GO
  342. --все собрания
  343. CREATE TABLE meeting (
  344.     meeting_date DATE NOT NULL,
  345.     meeting_place VARCHAR(50) NOT NULL,
  346.     committee_id INT NOT NULL,
  347.     chairman_id INT NOT NULL,
  348.     id_meeting INT PRIMARY KEY NOT NULL
  349.  
  350.     FOREIGN KEY (committee_id) REFERENCES committee(id),
  351.     FOREIGN KEY (chairman_id) REFERENCES units(id)
  352. )
  353. GO
  354.  
  355. INSERT INTO meeting VALUES
  356. ('20151124', 'Ленина, 15', 1, 1, 1),
  357. ('20151124', 'Ленина, 45', 2, 2, 2),
  358. ('20151124', 'Ленина, 1', 3, 3, 3),
  359. ('20151128', 'Советская, 12', 1, 1, 4)
  360. GO
  361.  
  362.  
  363. IF OBJECT_ID('meeting_structure', 'U') IS NOT NULL
  364.     DROP TABLE meeting_structure
  365. GO
  366. --участники собрания
  367. CREATE TABLE meeting_structure (
  368.     record_num INT PRIMARY KEY NOT NULL,
  369.     meet_id INT NOT NULL,
  370.     unit_id INT NOT NULL
  371.  
  372.     FOREIGN KEY (unit_id) REFERENCES units(id),
  373.     FOREIGN KEY (meet_id) REFERENCES meeting(id_meeting)
  374. )
  375. GO
  376.  
  377. --проверить, чтобы один человек не может заседать в 2 коммиссиях сразу
  378. IF OBJECT_ID('trig_meet', 'U') IS NOT NULL
  379.     DROP TRIGGER trig_meet
  380. GO
  381.  
  382. CREATE TRIGGER trig_meet ON meeting_structure AFTER INSERT
  383. AS
  384. BEGIN
  385.     DECLARE @counter INT;
  386.     SET @counter = (
  387.         SELECT COUNT(*)
  388.         FROM meeting_structure
  389.             INNER JOIN meeting AS Smeet ON Smeet.id_meeting = meeting_structure.meet_id
  390.         WHERE meeting_structure.record_num IN (
  391.             SELECT inserted.record_num
  392.             FROM inserted
  393.                 INNER JOIN meeting AS Imeet ON Imeet.id_meeting = inserted.meet_id
  394.             WHERE
  395.                 inserted.unit_id = meeting_structure.unit_id AND
  396.                 inserted.meet_id != meeting_structure.meet_id AND
  397.                 Smeet.meeting_date = Imeet.meeting_date AND
  398.                 Smeet.committee_id != Imeet.committee_id
  399.         )
  400.     )
  401.     IF (@counter > 1)
  402.     BEGIN
  403.         print ('Данный человек уже находится на одном из собраний в данное время');
  404.         ROLLBACK TRANSACTION;
  405.         RETURN
  406.     END
  407. END
  408. GO
  409.  
  410. INSERT INTO meeting_structure VALUES
  411. (1, 1, 1)
  412. INSERT INTO meeting_structure VALUES
  413. (2, 2, 2)
  414. INSERT INTO meeting_structure VALUES
  415. (3, 3, 3)
  416. GO
  417.  
  418. INSERT INTO meeting_structure VALUES
  419. (4, 4, 1),
  420. (5, 4, 8)
  421. GO
  422.  
  423. --списки коммиссий
  424. SELECT committee.questions AS 'Название комитета',
  425.        units.surname AS 'Фамилия',
  426.        units.name AS 'Имя',
  427.        units.patronymic AS 'Отчество'
  428. FROM STRUCTURE
  429.     INNER JOIN units ON units.id = STRUCTURE.unit_id
  430.     INNER JOIN committee ON committee.id = STRUCTURE.committee_id
  431. ORDER BY committee.questions
  432. GO
  433.  
  434. SELECT* FROM STRUCTURE
  435. GO
  436.  
  437. -- председатели за определенный период для конкретной коммиссии
  438. DECLARE @START DATE = '20000101';
  439. DECLARE @END DATE = '20151128';
  440. DECLARE @committee INT=1;
  441. SELECT units.surname AS 'Фамилия',
  442.        units.name AS 'Имя',
  443.        units.patronymic AS 'Отчество',
  444.        STRUCTURE.chairmanFirstDay AS 'Начало работы председателем',
  445.        STRUCTURE.chairmanLastDay AS 'Окончание работы председателем'
  446. FROM STRUCTURE
  447.     INNER JOIN units ON units.id = STRUCTURE.unit_id
  448. WHERE STRUCTURE.committee_id = @committee AND
  449.     (STRUCTURE.inclusion > @START OR STRUCTURE.inclusion = @START) AND
  450.     (STRUCTURE.expulsion < @END OR STRUCTURE.expulsion = @END OR STRUCTURE.expulsion IS NULL)
  451.     AND STRUCTURE.isChairman = 1
  452. ORDER BY STRUCTURE.chairmanFirstDay
  453. GO
  454.  
  455.  
  456. --для каждого члена думы коммитеты, в которых он состоит
  457. DECLARE @curr_date DATE = CONVERT (DATE, GETDATE());
  458. print(@curr_date)
  459. SELECT units.surname AS 'Фамилия',
  460.        units.name AS 'Имя',
  461.        units.patronymic AS 'Отчество',
  462.        committee.questions AS 'Коммитет',
  463.        STRUCTURE.isChairman AS 'Был ли председателем'
  464. FROM STRUCTURE
  465.     INNER JOIN units ON units.id = STRUCTURE.unit_id
  466.     INNER JOIN committee ON committee.id = STRUCTURE.committee_id
  467. WHERE STRUCTURE.expulsion IS NULL OR STRUCTURE.expulsion > @curr_date
  468. GO
  469.  
  470.  
  471. -- Для указанного интервала дат и комиссии выдать список членов с указанием количества пропущенных заседаний.
  472. -- Добавить тех, кто пропустил собрание
  473.  
  474.  
  475. CREATE FUNCTION consisted()
  476. RETURNS @ret_consist TABLE(
  477.     id INT PRIMARY KEY,
  478.     missed INT NOT NULL)
  479. AS
  480. BEGIN
  481.  
  482.     DECLARE @START DATE = '20000101';
  483.     DECLARE @END DATE = '20151128';
  484.     DECLARE @committee INT=1;
  485.  
  486.     DECLARE @units INT = (SELECT COUNT(*) FROM units)
  487.     DECLARE @counter INT = 1
  488.     DECLARE @temp_table TABLE (
  489.         tid INT PRIMARY KEY,
  490.         tmissed INT NOT NULL
  491.     )
  492.     WHILE (@counter <= @units)
  493.     BEGIN
  494.         DECLARE @meetings INT = (SELECT COUNT(*) FROM meeting)
  495.         DECLARE @counter_m INT = 1
  496.         DECLARE @missed INT = 0
  497.         WHILE(@counter_m <= @meetings)
  498.         BEGIN
  499.              IF (EXISTS (SELECT *
  500.                          FROM meeting_structure
  501.                          INNER JOIN meeting ON meeting.id_meeting = meeting_structure.meet_id
  502.                          WHERE meeting_structure.meet_id = @counter_m AND
  503.                                meeting_structure.unit_id = @counter AND
  504.                                (meeting_date > @START OR  meeting_date = @START) AND
  505.                                (meeting_date < @END OR meeting_date = @END)
  506.                         )
  507.                 )
  508.                 BEGIN
  509.                 SET @missed = @missed + 1
  510.                 END
  511.             SET @counter_m = @counter_m + 1
  512.            
  513.         END
  514.         INSERT INTO @temp_table VALUES(@counter, @missed)
  515.         SET @counter = @counter + 1
  516.     END
  517.  
  518.     INSERT @ret_consist
  519.     SELECT *
  520.     FROM @temp_table
  521.     RETURN
  522. END
  523. GO
  524.  
  525. SELECT * FROM units
  526. GO
  527.  
  528. SELECT * FROM STRUCTURE
  529. GO
  530.  
  531. SELECT * FROM meeting
  532. GO
  533.  
  534. SELECT * FROM meeting_structure
  535. GO
  536.  
  537. SELECT units.surname AS 'Фамилия',
  538.        units.name AS 'Имя',
  539.        units.patronymic AS 'Отчество',
  540.        consisted.missed AS 'Пропущено'  
  541. FROM consisted()
  542.     INNER JOIN units ON units.id = consisted.id
  543. GO
  544.  
  545.  
  546. -- Вывести список заседаний в указанный интервал дат в хронологическом порядке, для каждого заседания – список присутствующих.
  547. DECLARE @START DATE = '20000101';
  548. DECLARE @END DATE = '20151128';
  549. SELECT committee.questions AS 'Комитет',
  550.        meeting.meeting_date AS 'Дата собрания',
  551.        units.surname AS 'Фамилия',
  552.        units.name AS 'Имя',
  553.        units.patronymic AS 'Отчество'
  554. FROM meeting
  555.     INNER JOIN committee ON committee.id = meeting.committee_id
  556.     INNER JOIN meeting_structure ON meeting_structure.meet_id = meeting.id_meeting
  557.     INNER JOIN units ON units.id = meeting_structure.unit_id
  558. WHERE (meeting.meeting_date > @START OR meeting.meeting_date = @START) AND
  559.     (meeting.meeting_date < @END OR meeting.meeting_date = @END)
  560. ORDER BY meeting.meeting_date
  561. GO
  562.  
  563.  
  564. --По каждой комиссии показать количество проведенных заседаний в указанный период времени
  565. DECLARE @START DATE = '20000101';
  566. DECLARE @END DATE = '20151128';
  567.  
  568. SELECT committee.questions AS 'Комитет',
  569.        COUNT(meeting.id_meeting) AS 'Число собраний'
  570. FROM meeting
  571.     INNER JOIN committee ON committee.id = meeting.committee_id
  572. GROUP BY committee.questions
Advertisement
Add Comment
Please, Sign In to add comment