#mysql #sql #postgresql
#mysql #sql #postgresql
Вопрос:
У меня есть следующие таблицы:
Suppliers(Sno, Sname, Address)
Parts(Pno, Pname, Colour)
Catalogue(Sno, Pno, Price)
и я хочу найти Sno поставщиков, которые поставляют каждую деталь.
На данный момент я написал это:
SELECT s.sname
FROM suppliers s JOIN catalogue c
USING s.sno
Теперь, как мне написать часть «поставщики, которые поставляют каждую деталь»?
Я думал о том, чтобы иметь count (*) из parts = count (pno) для каждого Sno поставщика. Не мог бы кто-нибудь, пожалуйста, дать мне подсказку / написать первую часть равенства?
Спасибо!
Комментарии:
1. Хотелось бы верить, что это не домашнее задание. База данных поставщиков и деталей является классической в учебниках (особенно Криса Дейта), а поставщик, который поставляет все детали, является классическим примером реляционного разделения.
2. Если это подлинник, спросите своего бизнес-аналитика, хотят ли они разделения с остатками или без остатков, и что произойдет, когда набор деталей пуст (например, могут ли все поставщики не поставлять детали?) Если это домашнее задание, скажите своему учителю, чтобы он придумал более оригинальное задание 🙂
3. У меня нет проблем с преподавателем, использующим примеры из прошлого, пока пример чему-то учит. Вероятно, наиболее верно для классов для начинающих.
Ответ №1:
SELECT s.sname
FROM suppliers s
INNER JOIN catalogue c
ON s.Sno = c.Sno
GROUP BY s.sname
HAVING COUNT(c.Pno) = (SELECT COUNT(Pno) FROM Parts)
Ответ №2:
Вы близки. Вам нужно добавить предложение group by / having с подзапросом:
group by s.sname having count(*) = (select count(*) from catalogue)
Ответ №3:
По-моему, вы могли бы написать
SELECT s.Sno
FROM suppliers s
WHERE NOT EXISTS (
SELECT p.Pno
FROM parts p
WHERE NOT EXISTS (
SELECT c.*
FROM catalogue c
WHERE c.Pno = P.Pno
AND c.Sno = S.Sno
)
)
т. е. поставщик, которого не существует (деталь, которую мы не поставляем), для решения, позволяющего избежать подсчета. Понятия не имею, будет ли это более или менее эффективно, чем подсчеты.
Комментарии:
1. Возможно, стоит упомянуть, что этот метод называется «Разделение отношений», я полагаю, более подробную информацию можно найти здесь: simple-talk.com/sql/t-sql-programming /…
Ответ №4:
SELECT s.Sno, s.Sname
FROM Suppliers s
CROSS JOIN Parts p
LEFT JOIN Catalogue c ON s.Sno = c.Sno AND p.Pno = c.Pno
GROUP BY s.Sno, s.Sname
HAVING COUNT(*) = COUNT(c.Pno)
Ответ №5:
Попробуйте это:
alter proc clr
@c char(10),
@pno int output
as
begin
declare @f int
if exists(select p# from p where colour=@c)
begin
select @pno=p# from p where colour=@c
--set @f=1
end
-- else
-- set @f=0
-- return @f
end
--clr 'red',2
select p# from p where colour='red'
alter proc prcs
@c char(20)
as
begin
declare @pno numeric(2)
declare @f int
exec @f=clr @c,@pno output
--if @f=1
-- begin
select @pno
select s# from sp where p#=@pno
--set @i=1
-- end
--set @i=0
--return @i
end
prcs 'red'
select * from sp
select * from p,sp where p.p#=sp.p# and colour='red'
alter proc prcj
@c char(10)
as
begin
declare @i int
exec @i=prcs @c
if @i=1
begin
print'list of supplier'
select sname from s
where s#=@c
end
else
print'this record is not found'
end