Шпоры по базам данных2 / Шпора по БД
.doc1 Извлечь все различные пары продуктов, имеющих одинаковую калорийность. Указать коды и названия продуктов, их калорийность. Для продуктов, не имеющих пары, соответствующие значения – Null. Результат упорядочить по калорийности, затем – по названиям.
select A.pno, A.pname, B.pno, B.pname, A.kal
from prod as A left join prod as B on A.kal=B.kal and A.pno<>B.pno
order by A.kal, A.pname
2 Извлечь блюда, для которых заданы продукты, и продукты, которые используются в блюдах.
Результат должен содержать колонки: «код» (блюда или продукта); «название»; «тип»
(значения – «блюдо» или «продукт»); «использование» (для блюда – число продуктов в этом
блюде, для продукта – число блюд с этим продуктом). Упорядочить по типам,
затем – по названиям.
select bl.bno as nom, bl.bname as nam, 'bludo' as tip
from bl inner join rec on bl.bno=rec.bno
group by bl.bno, bl.bname
union
select prod.pno as nom, prod.pname as nam, 'product' as tip
from prod inner join rec on prod.pno=rec.pno
group by prod.pno, prod.pname
order by tip , nom
3 Извлечь коды и названия всех блюд, для которых либо вовсе не указаны входящие в него продукты, либо указан всего один продукт, причем такой, что калорийность его ниже 50 ед. Результат упорядочить по названиям блюд.
select bl.bno, bl.bname
from (bl left join rec on bl.bno=rec.bno) left join prod on prod.pno=rec.pno
where bl.bno in(
select bl.bno
from (bl left join rec on bl.bno=rec.bno) left join prod on prod.pno=rec.pno
group by bl.bno, bl.bname
having count(*)<=1 )
and isnull(prod.kal,0)<50
4 Извлечь сведения о блюдах с калорийностью ниже 500 ед.: код, название, количество продуктов, входящих в блюдо. Калорийность блюда рассчитывать как произведение калорийности продукта на количество продукта в блюде, просуммированное по всем продуктам, входящим в блюдо.
select bl.bno, bl.bname, count(*) as KvoProdVBl, sum(rec.kol*prod.kal) as Kalorinost
from (bl left join rec on bl.bno=rec.bno) left join prod on prod.pno=rec.pno
group by bl.bno, bl.bname
having sum(rec.kol*prod.kal)<500
5 Извлечь статистику уровней калорийности продуктов: уровень калорийности, количество
продуктов, имеющих эту калорийность, количество блюд, содержащих продукты этой
калорийности. Не учитывать продукты, названия которых начинаются на «А», и блюда
категории «Б». Упорядочить по убыванию калорийности.
select prod.kal, count(distinct prod.pno) as KvoProdSEtoiKal,count(rec.bno) as KvoBlud
from prod left join rec on prod.pno=rec.pno
where rec.bno in (
select bl.bno
from bl
where bl.kat<>'b')
and prod.pname not like 'a%'
or prod.pno not in (
select prod.pno
from prod, rec
where prod.pno=rec.pno)
group by prod.kal
order by prod.kal desc
6 Извлечь сведения о блюдах с калорийностью выше калорийности блюда с кодом «123»: код, название, калорийность. Учитывать только блюда, приготавливаемые более, чем из трех продуктов. Калорийность блюда рассчитывать как произведение калорийности продукта на количество продукта в блюде, просуммированное по всем продуктам, входящим в блюдо.
select bl.bno, bl.bname, sum(rec.kol*prod.kal) as Kalorinost
from (bl left join rec on bl.bno=rec.bno) left join prod on prod.pno=rec.pno
where bl.bno in(
select bl.bno
from (bl left join rec on bl.bno=rec.bno) left join prod on prod.pno=rec.pno
group by bl.bno
having sum(rec.kol*prod.kal)>(
select sum(rec.kol*prod.kal)
from (bl left join rec on bl.bno=rec.bno) left join prod on prod.pno=rec.pno
where bl.bno='b2' ))
group by bl.bno, bl.bname
having count(*)>3
7 Извлечь коды и названия блюд, содержащих в точности все те продукты, которые содержит блюдо «Солянка московская». Отсортировать результат в алфавитном порядке названий блюд.
select bl.bno, bl.bname
from bl left join rec on bl.bno=rec.bno
where not exists(
select *
from rec where rec.bno in(
select bl.bno
from bl
where bl.bname='pelm')
and rec.pno not in(
select rec.pno
from rec
where bl.bno=rec.bno))
and bl.bname<>'pelm'
group by bl.bno, bl.bname
having count(*)=(
select count(*)
from bl left join rec on bl.bno=rec.bno
where rec.bno in(
select bl.bno
from bl
where bl.bname='pelm')
group by bl.bno)
order by bl.bname
8 Извлечь номера и названия блюд, содержащих в количестве более 100 ед., по крайней мере, все те продукты, которые содержит блюдо «Солянка балтийская». Отсортировать результат в обратном алфавитном порядке названий блюд.
select bl.bno, bl.bname
from bl
where not exists (
select *
from rec
where rec.bno in (
select bl.bno
from bl
where bl.bname='pelm')
and rec.pno not in (
select pno
from rec
where rec.bno=bl.bno and rec.kol>100 ))
order by bl.bname desc
9 Извлечь коды и названия блюд, не содержащих в количестве более 100 ед. ни одного продукта из тех, которые содержит блюдо «Солянка уфимская». Отсортировать результат в обратном порядке кодов блюд.
select distinct bl.bno, bl.bname
from bl
where not exists (
select *
from rec
where rec.bno in (
select bl.bno
from bl
where bl.bname='pelm')
and rec.pno in (
select pno
from rec
where rec.bno=bl.bno and rec.kol>100))
order by bl.bno desc
10 Извлечь все пары предметов с одинаковым объемом часов, ведущихся на одном курсе одной специальности. Указать коды и названия предметов, их объем. Для предметов, не имеющих пары, соответствующие значения – Null. Результат упорядочить по объему, затем – по названиям.
select a.pno , a.pname, b.pno, b.pname, a.ob
from pr as a left join pr as b on a.ob=b.ob and a.pno<>b.pno and a.kurs=b.kurs and a.spec=b.spec
order by a.ob, a.pname
11 Извлечь студентов, которые имеют оценки, и предметы,
по которым получены оценки. Результат должен содержать колонки: «код» (студента / предмета); «имя»
(фио студента / название предмета); «тип» («студент» /
«предмет»); «сдач» (число оценок у студента / по предмету). Упорядочить по типам, затем – по именам.
select st.sno as kod, st.fio as nazvanie, 'student' as tip, count(*) as sdach
from st inner join usp on st.sno=usp.sno
group by st.sno, st.fio
union
select pr.pno as kod, pr.pname as nazvznie, 'predmet' as tip, count(*) as sdach
from pr inner join usp on pr.pno=usp.pno
group by pr.pno, pr.pname
order by tip, nazvanie
12 Извлечь коды и названия предметов, по которым либо вовсе отсутствуют оценки, либо получена всего одна оценка студентом первого курса. Результат упорядочить по названиям.
select pr.pno, pr.pname
from pr
where not exists(
select *
from usp
where pr.pno=usp.pno)
or pr.pno in(
select pno
from st left join usp on st.sno=usp.sno
where st.kurs=1
group by pno
having count(*)=1)
13 Извлечь сведения о студентах, у которых суммарный объем сданных предметов превышает 1000 час: код, фио, количество и средний балл. Упорядочить по курсам, далее по специальностям, далее по группам, далее по фио.
select st.sno, st.fio, count(*) as kolvo, avg(pr.ob) as SrBal
from (st left join usp on st.sno=usp.sno) left join pr on pr.pno=usp.pno
group by st.sno, st.kurs, st.spec, st.gr, st.fio
having sum(pr.ob)>1000
order by st.kurs, st.spec, st.gr, st.fio
14 Извлечь статистику успеваемости студенческих групп: идентификатор группы (специальность, курс, группа), количество студентов в группе, количество предметов, по которым имеются оценки, средний балл. Не учитывать предметы объемом менее 15 час. Упорядочить по идентификаторам группы.
select st.spec, st.kurs, st.gr, count(distinct st.sno) as KvoStud, avg(usp.oc) as SrBal
from (st left join usp on st.sno=usp.sno) left join pr on pr.pno=usp.pno
where pr.pno in(
select pr.pno
from pr
where pr.ob>=15)
group by st.spec, st.kurs, st.gr
order by st.spec, st.kurs, st.gr
15 Извлечь сведения о студентах, у которых средний балл по предметам текущего курса выше, чем у студента с кодом «123123»: код, фио, средний балл. Учитывать только студентов, имеющих оценки более, чем по одному предмету.
select st.sno, st.fio, avg(usp.oc) as SrBal
from (st left join usp on st.sno=usp.sno) left join pr on pr.pno=usp.pno
group by st.sno, st.fio
having avg(usp.oc)>(
select avg(usp.oc)
from usp
where usp.sno='s2')
and count(*)>1
16 Извлечь коды и фио студентов, получивших оценки в
точности по тем предметам, по которым имеет оценки студент Иванов П.С., АСУ-347. Отсортировать результат в алфавитном порядке фио.
select st.sno, st.fio
from st left join usp on st.sno=usp.sno
where not exists(
select *
from usp
where usp.sno in(
select st.sno
from st
where st.fio='Anischenko' and st.spec='ASOI'
and st.kurs=3 and st.gr='26' )
and usp.pno not in(
select usp.pno
from usp
where st.sno=usp.sno) )
and (st.fio<>'Anischenko' or st.spec<>'ASOI'
or st.kurs<>3 or st.gr<>'26')
group by st.sno, st.fio
having count(*)=(
select count(*)
from st left join usp on st.sno=usp.sno
where st.fio='Anischenko' and st.spec='ASOI'
and st.kurs=3 and st.gr='26')
order by st.fio desc
17 Извлечь коды и названия предметов, по которым получили отличные оценки, по крайней мере, все те студенты, которые сдали на хорошо и отлично предмет «Базы данных». Отсортировать результат в обратном алфавитном порядке названий.
select pno, pname
from pr
where not exists (
select *
from usp
where sno in(
select usp.sno
from pr inner join usp on pr.pno=usp.pno
where (usp.oc=4 or usp.oc=5) and pr.pname='mat')
and pr.pno=usp.pno and oc<>5)
and pno in(
select pno
from usp
where pr.pno=usp.pno)
order by pname desc
18 Извлечь коды и фамилии студентов, не сдавших на «отлично» ни одного предмета из тех, которые сдал на «отлично» студент Иванов П.С. из АСУ-347 (предполагается, что этот студент сдал на «отлично» хотя бы один предмет). Отсортировать результат в обратном порядке кодов.
select distinct usp.sno, st.fio
from st left join usp on st.sno=usp.sno
where usp.oc<>5 and pno in(
select pno
from usp
where usp.oc=5 and usp.sno in(
select sno
from st
where st.fio='Bogdanova'))
order by usp.sno desc
19 Извлечь все пары врачей одной специальности, такие, что стаж второго напарника не меньше стажа первого. Для каждого напарника указать код, фио, специальность. Для врачей, не имеющих пары, значения напарника – Null. Результат упорядочить по фио напарников.
select a.vno, a.vname, b.vno, b.vname, a.spec
from vr as a left join vr as b on a.spec=b.spec and a.staj<b.staj
order by a.vname, b.vname
20 Извлечь пациентов, посетивших врача в текущем году, и врачей, принявших пациентов тоже в текущем году. Результат должен содержать: «код» (пациента / врача); «фио»; «тип» («пациент» / «врач»); «приемов» (число приемов у пациента / врача). Упорядочить по типам, затем – по фио.
select pac.pno as nom, pac.pname as nam, 'pacient' as tip, count(*) as KvoPoseshenii
from pac left join pr on pac.pno=pr.pno
where pr.datapr like '%2006%'
group by pac.pno, pac.pname
union
select vr.vno as nom, vr.vname as nam, 'vrach' as tip, count(*) as KvoPoseshenii
from vr left join pr on vr.vno=pr.vno
where pr.datapr like '%2006%'
group by vr.vno, vr.vname
order by tip, nam
21 Извлечь коды и фио пациентов категории «пенсионер», которые в текущем году либо не посещали врача-терапевта, либо посещали неоднократно врача-окулиста. Результат упорядочить по фио пациентов.
select pno, pname
from pac
where pno not in(
select pac.pno
from pac left join pr on pac.pno=pr.pno
where vno in(
select vno
from vr
where spec='terapevt')
and pr.datapr like '%2006%')
or pno in(
select pr.pno
from vr left join pr on vr.vno=pr.vno
where spec='okulist'
group by pr.pno
having count(*)>1)
order by pname
22 Извлечь сведения о врачах-терапевтах с загруженностью в январе месяце выше 0,75: код, фио, количество принятых пациентов. Загруженность за месяц рассчитывается как деленное на 200 число принятых пациентов. Не учитывать пациентов категории «Сторонний». Результат упорядочить по Фио.
select vr.vno, vr.vname, count(*) as KvoPac
from vr left join pr on vr.vno=pr.vno
where vr.spec='terapevt'
and pr.datapr like '%Jan%'
group by vr.vno, vr.vname
having count(*)/200>0.75
order by vr.vname
23 Извлечь статистику посещений: категория пациента, количество приемов пациентов этой категории, количество врачей, принявших пациентов этой категории. Не учитывать пациентов, родившихся до 1 января 1913, и врачей со стажем менее 1 года. Упорядочить по категориям.
select pac.kat, count(distinct pr.datapr) as KvoPr, count(distinct pr.vno) KvoVr
from (pac left join pr on pac.pno=pr.pno) left join vr on vr.vno=vr.vno
where staj>1
group by pac.kat
order by kat
24 Извлечь сведения о врачах той же специальности, что и врач с кодом «123», но принявших в текущем году больше пациентов: код, фио, число принятых пациентов. Учитывать только врачей, принявших более 10 пациентов.
select vr.vno, vr.vname, count(*) as KvoPr
from vr left join pr on vr.vno=pr.vno
where vr.spec = (
select vr.spec
from vr
where vr.vno='v2')
and pr.datapr like '%2006%'
group by vr.vno, vr.vname
having count(*)>(
select count(*)
from vr left join pr on vr.vno=pr.vno
where vr.vno='v2' and pr.datapr like '%2006%')
25 Извлечь коды и фио врачей, принявших в точности тех пациентов, которых принял врач-терапевт Иванов П.С. Отсорт результат в алфавитном порядке фио.
select vno, vname
from vr
where not exists(
select *
from pr
where vno in(
select vno
from vr
where vname='Hasanov' and spec='terapevt')
and pr.pno not in(
select pno
from pr
where pr.vno=vr.vno))
and vno in(
select vno
from pr
group by vno
having count(*)=(
select count(*)
from pr
where vno in(
select vno
from vr
where vname='Hasanov' and spec='terapevt')))
33 Извлечь сведения об изделиях, у которых суммарная цена используемых деталей по крайней мере в два раза меньше стоимости изделия: код, название, стоимость, суммарное число деталей, суммарная цена деталей.
select izd.ino, izd.iname, izd.stoim, sum(qty) as VsegoDet, sum(prise*qty) as StoimVsehDet
from (izd left join sost on izd.ino=sost.ino) left join det on det.dno=sost.dno
group by izd.ino, iname, stoim
having sum(prise*qty)<izd.stoim/2
26 Извлечь коды и фио пациентов, посетивших с начала этого года, по крайней мере, всех тех врачей, которых посетил пациент Иванов С.П. Отсортировать результат в обратном порядке кодов.
select distinct pac.pno, pac.pname
from pac
where not exists(
select *
from pr
where pno in(
select pno
from pac
where pname='Anischenko' )
and vno not in(
select vno
from pr
where pr.pno=pac.pno and datapr>'Jan 1, 2006'))
order by pac.pno desc
27 Извлечь коды и фио пациентов, не посетивших в текущем году ни одного врача из тех, которых посетил пациент Иванов С.П.. Отсортировать результат в обратном порядке кодов.
select pno, pname
from pac
where not exists(
select *
from pr
where pno in(
select pno from pac
where pname = 'Anischenko')
and vno in(
select vno
from pr
where pr.pno=pac.pno and pr.datapr>'Jan 1, 2006'))
28 Извлечь все пары изделий одного вида, такие, что стоимость второго изделия пары не превышает стоимость первого. Для каждого элемента пары указать код, название, стоимость. Для изделий, не имеющих пары, значения напарника – Null. Результат упорядочить по названиям изделий.
select a.ino, a.iname, a.stoim, b.ino, b.iname, b.stoim
from izd as a left join izd as b
on a.vid=b.vid and a.stoim>=b.stoim and a.ino<>b.ino
order by a.iname
29 Извлечь изделия, для которых указаны детали, и детали, которые входят в состав изделий. Результат должен содержать колонки: «код» (изделия / детали); «название» (изделия / детали); «тип» («изделие» / «деталь»); «количество» (суммарное число деталей в изделии / изделий, содержащих деталь). Упорядочить по типам, затем – по названиям.
select izd.ino as nomer, izd.iname as nazv, 'izdelie' as tip, count(*) as Kolvo
from izd inner join sost on izd.ino=sost.ino
group by izd.ino, izd.iname
union
select det.dno as nomer, det.dname as nazv, 'detal' as tip, count(*) as Kolvo
from det inner join sost on det.dno=sost.dno
group by det.dno, det.dname
order by tip, nazv
30 Извлечь коды и названия изделий, для которых либо вовсе не указаны детали, либо указана единственная деталь ценой меньше 1 руб в количестве меньше 10. Результат упорядочить по названиям.
select izd.ino, izd.iname
from izd
where not exists(
select * from sost
where sost.ino=izd.ino)
or (izd.ino in(
select ino from sost
group by ino
having count(*)=1)
and izd.ino in(
select izd.ino
from (izd inner join sost on izd.ino=sost.ino) inner join det on det.dno=sost.dno
where det.prise<40 and sost.qty<10))
order by iname
31 Извлечь сведения о деталях, среднее количество которых в изделии превышает 200: код, название, количество изделий, использующих деталь, и суммарное количество деталей во всех использующих ее изделиях. Учитывать изделия стоимостью выше 100 руб. Упорядочить по названиям.
select det.dno, det.dname, count(*) as KvoIzd, sum(sost.qty) as VsegoDet
from (det left join sost on det.dno=sost.dno) left join izd on izd.ino=sost.ino
where izd.stoim>100
group by det.dno, det.dname
having avg(qty)>200
32 Извлечь статистику видов изделий: вид, число изделий данного вида, количество различных деталей в них, суммарное количество используе-мых в них деталей. Не учитывать изделия дешевле 100 руб и детали дешевле 10 руб. Упорядочить по видам.
select izd.vid, count(distinct izd.ino) as ChisloIzdVida, count(distinct sost.dno) as KvoRaznDet, sum(qty) as VsegoDet
from (izd left join sost on izd.ino=sost.ino) left join det on det.dno=sost.dno
where izd.stoim>=100 and det.prise>=10
group by izd.vid
order by vid
34 Извлечь коды и названия изделий, использующих в точности те детали, которые используются в изделии «SyncMaster 171s». Отсортировать результат в алфавитном порядке названий.
select ino, iname
from izd
where not exists(
select * from sost
where ino in(
select ino from izd
where iname='izd3')
and dno not in(
select dno from sost
where sost.ino=izd.ino))
and ino in(
select ino
from sost
group by ino
having count(*)=(
select ount(*) from sost
where ino in(
select ino
from izd
where iname='izd3')))
order by iname
35 Извлечь коды и названия деталей, которые используются в количестве больше 20 штук, по крайней мере, во всех тех изделиях, в которых используется деталь «Шайба». Отсортировать результат в алфавитном порядке названий.
select dno, dname
from det
where not exists(
select *
from sost
where dno in(
select dno
from det
where dname='det3')
and ino not in(
select ino
from sost
where sost.dno=det.dno and qty>20))
36 Извлечь коды и названия изделий, не использующих в количестве более 100 штук ни одной детали из тех, которые применяются в изделии «SyncMaster 171s». Отсортировать результат в обратном порядке кодов.
select ino, iname
from izd
where not exists(
select *
from sost
where ino in(
select ino
from izd
where iname='izd2')
and dno in(
select dno
from sost
where sost.ino=izd.ino and qty>100))