Найдите номер поставщика для тех поставщиков, которые поставляют каждую деталь

#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