2011-11-20 15 views
8

Masz tabelę SQL table z dwiema kolumnami: name i pen. Obie kolumny są ciągami tekstowymi.Bardzo trudny wywiad SQL (nie można użyć procedury przechowywanej)

name | pen 
---------------  
mike | red 
mike | red 
mike | blue 
mike | green 
steve | red 
steve | yellow 
anton | red 
anton | blue 
anton | green 
anton | black 
alex | black 
alex | green 
alex | yellow 
alex | red 

Jako argument wejściowy podano nazwę osoby.

Proszę napisać instrukcję SQL (nie procedurę przechowywaną), która zwraca nazwiska osób posiadających unikalny zestaw długopisów, który jest równoważny lub szerszy/większy niż zestaw długopis danej osoby.

Przykłady:

  • wejściowe Mike
  • Wydajność: Anton

Mike ma (czerwony, niebieski, zielony).
Anton ma więcej gadżetów (czerwony, niebieski, zielony) + czarny.

  • wkład: Steve
  • wyjściowa: Alex

Steve (czerwony, żółty).
Alex ma (czerwony, żółty) + zielony + czarny.
Mike, Anton nie są drukowane - nie mają żółtego.

  • wejściowe: Alex
  • wyjściowa:
+0

Witamy StackOverflow : jeśli umieścisz kod, XML lub próbki danych, ** proszę ** zaznacz te linie w edytorze tekstu i kliknij przycisk "próbki kodu" ('{}') na pasku narzędzi edytora, aby ładnie sformatować i podświetlić składnię! –

+1

Czy to ** Twoja ** praca domowa ?. Co zrobiłeś do tej pory? – joaquin

+6

[To jest podział relacyjny.] (Http://www.simple-talk.com/sql/t-sql-programming/divided-we-stand-the-sql-of-relational-division/) –

Odpowiedz

13

Oto jeden ze sposobów (Online Demo), przyjmując imię wejściowego "Steve".

to można przeformułować jako „Patrząc na wszystkich użytkowników, dla których nie istnieje pióro posiadanych przez Steve, które nie są właścicielami”

SELECT DISTINCT name 
FROM table t1 
WHERE NOT EXISTS (SELECT * 
        FROM table t2 
        WHERE name = 'steve' 
          AND NOT EXISTS (SELECT * 
              FROM table t3 
              WHERE t2.pen = t3.pen 
               AND t1.name = t3.name)) 
AND t1.name <> 'steve' /*Exclude input name from results*/ 

See this article for other techniques

+0

Dzięki, Martin , wystarczy dodać jeszcze jeden warunek: SELECT DISTINCT nazwy z tabeli t1 WHERE NOT EXISTS (SELECT * FROM tabela t2 WHERE name = 'Alex' AND NOT EXISTS (SELECT * FROM tabela t3 GDZIE t2.pen = t3 .pen AND t1.name = t3.name)) i nazwisko <> 'Alex' – user1055108

+0

@ user1055108 Przed tobą! (Jest już dodany) –

0
Table Format: 

E_NAME E_PEN 
---------------- 
mike green 
mike blue 
mike red 
mike red 
steve red 
steve yellow 
anton red 
anton blue 
anton green 
anton black 
alex black 
alex green 
alex yellow 
alex red 


Query: 



SELECT A.E_NAME, A.E_PEN 
    FROM V_NAME A, V_NAME B 
WHERE TRIM(UPPER(A.E_NAME)) = TRIM(UPPER(B.E_NAME)) 
    AND TRIM(UPPER(A.E_NAME)) != 'MIKE' 
    AND TRIM(UPPER(A.E_PEN)) = TRIM(UPPER(B.E_PEN(+))) 

Procedure to take Input from user: 

CREATE OR REPLACE PROCEDURE E_TEST(I_NAME VARCHAR2) AS 
BEGIN 
    EXECUTE IMMEDIATE 'CREATE TABLE E_TABLE AS 
        SELECT A.E_NAME,A.E_PEN FROM V_NAME A,V_NAME B 
        WHERE TRIM(UPPER(A.E_NAME)) = TRIM(UPPER(B.E_NAME)) 
        AND TRIM(UPPER(A.E_NAME)) != ''' || 
        I_NAME || ''' 
        AND TRIM(UPPER(A.E_PEN))= TRIM(UPPER(B.E_PEN(+)))'; 
END; 

Name: Nikhil Shinde 
E-Mail: [email protected] 
1
with test1 as 
    (select a.name nm, count(distinct a.pen) ct 
     from table a, table b 
    where b.pen = a.pen 
     and b.name = 'anton' 
    group by a.name 
    order by 2 desc), 
    test2 as 
    (select nm name1 
    from test1 
    where ct = (select max(ct) from test1)) 
    select distinct c.name 
    from table c 
    where c.name in (select name1 
         from test2 
         where name1 not in (case 
          when (select count(distinct name1) from test2) > 1 then 
           'anton' 
          else 
           ' ' 
          end)) 
0
declare @t table (name nvarchar(20), pen nvarchar(20)) 
insert into @t (name,pen) 
values('mike','red'), 
('mike','red'), 
('mike','blue'), 
('mike','green'), 
('steve','red'), 
('steve','yellow'), 
('anton','red'), 
('anton','blue'), 
('anton','green'), 
('anton','black'), 
('alex','black'), 
('alex','green'), 
('alex','yellow'), 
('alex','red') 

declare @input nvarchar(20) = 'mike'; 

with cte_input (name, pen) 
as 
(
    select distinct name, pen 
    from @t 
    where name = @input 
) 
, cte_colors (name, matches) 
as 
(
    select name, matches = count(distinct pen) 
    from @t 
    where name != @input  
     and pen in (select pen from cte_input) 
     group by name 
    having count(distinct pen) = (select count(1) from cte_input) 
) 
select t.name 
from @t t 
join cte_colors m on m.name = t.name 
group by t.name, m.matches 
having count(distinct t.pen) > m.matches 
0

Możemy użyć funkcji analitycznej LEAD, aby osiągnąć to rozwiązanie.

Zapytanie byłoby

select next_name from 
(select name, count(pen) CNT, LEAD(name,1) over (order by count(pen)) next_name 
from table 
group by name order by CNT 
) 
where name=input_value; 

zapytanie sub dadzą wyniki jak poniżej

nazwa | CNT | następna nazwa:

mike | 3 | Steve

steve | 2 | anton

anton | 4 | alex

alex | 4 | (null)

Następnie zapytanie wyszukuje wymagany wiersz i podaje numer next_name, którego szukamy.

0

tworzyć praktyki stołowego ( nazwa varchar (10), długopisy VARCHAR (10)

) praktyki insert (nazwa, długopisy) select 'Mike', 'czerwony' Union select 'Mike', 'czerwony' związek wybierz 'mike', 'niebieski' union wybierz 'mike', 'zielony' union wybierz 'steve', 'czerwony' union wybierz 'steve', 'yellow' union wybierz 'anton', "niebieski" związek wybierz "anton", "zielony" związek wybierz "anton", "czarny" związek sele TPA 'Anton', 'czerwony' unia select 'Alex', 'czarny' union select 'Alex', 'green' union wybierz 'Alex', 'żółty' związek wybierz 'Alex', 'czerwony'

select * w #t z praktyką

update #t 
set Colourcode = 1 where pens = 'black' 
go 
update #t 
set Colourcode = 2 where pens = 'blue' 
go 
update #t 
set Colourcode = 3 where pens = 'green' 
go 
update #t 
set Colourcode = 4 where pens = 'red' 
go 
update #t 
set Colourcode = 5 where pens = 'yellow' 

zaznaczyć wyraźną colourcode z #ti

/* Kod IMP / aktualizacja #ti zestawu Number = ( select count () od #ti gdzie name = 'Steve' a colourcode = 1 ) gdzie name = 'Steve' a colourcode = 1

/* raz powyższe stwierdzenie aktualizacji exected zmiana colourcode = 2 i ponownie uruchom oświadczenie zmiana colourcode = 3 i ponownie uruchomić zmiany colourcode oświadczenie = 4 i ponownie uruchomić zmiany colourcode oświadczenie = 5 i ponownie uruchomić oświadczenie */

/* Śledź ten sam proces nazwą „alex”,” anton 'i' mike '*/

/* Poniżej znajduje się rozwiązanie */

wybierz nazwę z #ti gdzie liczba = ( wybrać odrębny numer z #ti gdzie colourcode = 3 i Number = 1)

0
Declare @name nvarchar(20) 
set @name = 'steve'; 
with cte_in 
as 
(
select distinct Pen from tblNamePen where Name = @name 
) 

select Name from 
(
select t1.name, count(distinct t1.Pen) ct from tblNamePen t1 
join cte_in inp on t1.Name <> @name 
where t1.pen = inp.Pen 
group by t1.Name 
) a 
where a.ct >= (select count(Pen) from cte_in) 
Powiązane problemy