非常具有挑战性的SQL访谈(不能使用存储过程)

时间:2011-11-20 12:02:38

标签: sql

您有一个包含两列的SQL表tablenamepen。两列都是文本字符串。

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

将人名作为输入参数。

请写一个SQL语句(不是存储过程),它返回具有唯一一组笔的人的姓名,这些笔的数量等于或大于/大于给定人的一组笔。

示例:

  • 输入:mike
  • 输出:anton
迈克有(红色,蓝色,绿色) 安东有更多的小工具(红色,蓝色,绿色)+黑色。

  • 输入:steve
  • 输出:alex
史蒂夫有(红色,黄色) 亚历克斯有(红色,黄色)+绿色+黑色 迈克,安东没有印刷 - 他们没有黄色。

  • 输入:alex
  • 输出:

6 个答案:

答案 0 :(得分:13)

这是一种方式(Online Demo),假设输入名称为“steve”。

这可以改为“寻找没有史蒂夫所拥有的钢笔的所有用户,他们不拥有”

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

答案 1 :(得分: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))

答案 2 :(得分: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: nikhilshinde3jun@gmail.com

答案 3 :(得分:0)

我们可以使用LEAD分析功能来实现这个解决方案。

查询将是

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;

子查询将给出如下结果

名称| CNT | next_name

迈克| 3 |史蒂夫

史蒂夫| 2 |安东

anton | 4 |亚历克斯

alex | 4 | (空)

然后out out查询过滤所需的行,并提供我们正在寻找的next_name

答案 4 :(得分:0)

创建表练习 (  name varchar(10),pens varchar(10)

)  插入练习(名称,笔)  选择'迈克','红'联盟  选择'迈克','红'联盟  选择“迈克”,“蓝色”联盟  选择“迈克”,“绿色”联盟  选择'史蒂夫','红'联盟  选择'steve','yellow'union  选择'anton','blue'union  选择'anton','green'union  选择'anton','black'union  选择'anton','red'union  选择'alex','black'union  选择'alex','green'union  选择'alex','yellow'union  选择'alex','red'

从练习中选择*到#t

 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'

从#t

中选择不同的颜色代码

/ * IMP代码 / 更新#t 设置数字= ( 从#t中选择计数() 其中name ='steve'和colourcode = 1 ) 其中name ='steve'和colourcode = 1

/ *执行上述更新语句后,更改colourcode = 2并再次运行该语句                                               更改colourcode = 3并再次运行该语句                                               更改colourcode = 4并再次运行该语句                                               更改colourcode = 5并再次运行语句* /

/ *按照相同的流程命名'alex','anton'和'mike'* /

/ *以下是解决方案* /

从#t中选择名称 其中number = ( 从#t中选择不同的数字 其中colourcode = 3且Number = 1)

答案 5 :(得分: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)