Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/sql/84.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
SQL-比较两个集合_Sql_Oracle - Fatal编程技术网

SQL-比较两个集合

SQL-比较两个集合,sql,oracle,Sql,Oracle,比如说,我有员工,我知道他们喜欢什么水果 fruits(name, fruit_name) 我的问题是:列出所有至少和唐纳德一样喜欢水果的员工 那么我如何比较两组值呢 我就是这样得到唐纳德喜欢的水果的: Select name, fruit_name from fruits where initcap(name) like '%Donald%'; 唐纳德喜欢苹果、梨、桃子。我需要喜欢苹果、梨、桃子和其他水果的人,但他们必须喜欢这三种水果。您可以使用self-join获得所需的结果- 我对您的

比如说,我有员工,我知道他们喜欢什么水果

fruits(name, fruit_name)
我的问题是:列出所有至少和唐纳德一样喜欢水果的员工

那么我如何比较两组值呢

我就是这样得到唐纳德喜欢的水果的:

Select name, fruit_name
from fruits
where initcap(name) like '%Donald%';

唐纳德喜欢苹果、梨、桃子。我需要喜欢苹果、梨、桃子和其他水果的人,但他们必须喜欢这三种水果。

您可以使用self-join获得所需的结果- 我对您的查询进行了一些调整,以获得输出-

select distinct e1.name from fruits e1,(Select name, fruit_name
from fruits
where initcap(name) like '%Donald%') e2
where e1.fruit_name = e2.fruit_name;
上述查询返回至少有一个水果与Donald匹配的员工

下面测试的查询给出了至少所有唐纳德水果匹配的员工

     select name from (
    select name,count(1) cnt  from
    (select name,fruit_name, case when fruit_name in (Select distinct fruit_name
        from fruits
        where initcap(name) like '%Donald%') then 1 else 0 end fruit_match from fruits)
    where fruit_match = 1 group by name) where  cnt >=
 (select count(distinct fruit_name) from fruits where initcap(name) like '%Donald%');
这将为您提供所有员工的姓名,这些员工至少有一种与Donald相似的水果,尽管您应该注意,您获取所有Donald喜欢的水果的解决方案也会为您提供表示Ronald McDonald喜欢的水果

我知道你需要所有喜欢唐纳德喜欢的水果的人。这更难

SELECT DISTINCT emp.name
FROM employees emp
WHERE NOT EXISTS (
    SELECT *
    FROM fruits don_fruits
    LEFT JOIN fruits emp_fruits
        ON (don_fruits.fruit_name = emp_fruits.fruit_name AND emp_fruits.name = emp.name)
    WHERE INITCAP(don_fruits.name) LIKE '%Donald%'
      AND emp_fruits.name IS NULL
);

在oracle plsql中,我会使用类似的方式打印所有喜欢donald喜欢的所有水果的员工:

declare 
emp_name fruits.name%type;

begin

for rec in select distinct name from fruits
 loop

select name into emp_name from
(
 Select name, fruit_name
  from fruits
   where fruits.name=rec.name
 minus
   Select name, fruit_name
  from fruits
 where initcap(name) like '%Donald%'
)

if emp_name is null
 then
 dbms_output.put_line('Employee' || rec.name || 'likes same fruits as Donald');
end if

 end loop 

end
试试这个:

Select distinct f2.name 
from fruits f1, fruits f2 where f1.fruit_name = f2_fruit_name 
where initcap(f1.name) like '%Donald%';
有两种方法可以做到这一点:

使用集合 我发现这提供了最容易理解的SQL,但它确实需要定义集合类型:

CREATE TYPE VARCHAR2s_Table AS TABLE OF VARCHAR2(20);
然后,您可以将所有内容分组到集合中,并使用自联接和的子集合来查找其他名称

WITH grouped AS (
  SELECT name,
         CAST( COLLECT( fruit ) AS VARCHAR2s_Table ) AS list_of_fruits
  FROM   fruits
  GROUP BY name
)
SELECT g.name
FROM   grouped f
       INNER JOIN
       grouped g
       ON (     f.list_of_fruits SUBMULTISET OF g.list_of_fruits
            AND f.name <> g.name )
WHERE  f.name = 'Alice';
或此的替代版本:

WITH grouped AS (
  SELECT name,
        CAST( COLLECT( fruit ) AS VARCHAR2s_Table ) AS list_of_fruits
  FROM fruits
  GROUP BY name
)
SELECT name
FROM   grouped
WHERE  name <> 'Alice'
AND    ( SELECT list_of_fruits FROM grouped WHERE name = 'Alice' )
       SUBMULTISET OF list_of_fruits ;
不使用集合
顺便说一句,使用像“%Name%”这样的INITCAPName有可能匹配多个名称,您可能会发现您正在找到一些人喜欢的结果。

我不熟悉initcap函数。你在用什么数据库管理系统?我想是的,Oracle。Initcap仅用于将donald或donald转换为donald。请从水果f1中选择不同的f2.name,其中f1.fruit_name=f2_fruit_name,其中initcapf1.name类似于“%donald%”@wxyz将您的评论作为答案发布,否则OP无法将其作为解决方案。您的答案假设employee表中有一个名为fruit_name的列。根据员工只有一个名为name-employeename-fruitsname的列的问题,实际上根本不需要员工。我认为这是不对的。我需要找到和唐纳德一样喜欢水果的名字。例:Donald喜欢苹果、梨、桃子,输出应该是喜欢苹果、梨、桃子和可能更多水果的人。最好是将表格正常化,或者从原始问题中排除employee表格altogher。@Arnab:-我错写了employee table我指的是水果本身。已在上面的查询中更改了相同的内容。上述查询将返回喜欢与Donald相同水果的员工的姓名。将在sql fiddle中确认相同内容,并向您发送链接Please ceck for sntax错误,我还没有在我的机器上实际运行此操作
WITH grouped AS (
  SELECT name,
         CAST( COLLECT( fruit ) AS VARCHAR2s_Table ) AS list_of_fruits
  FROM   fruits
  GROUP BY name
)
SELECT g.name
FROM   grouped f
       INNER JOIN
       grouped g
       ON (     f.list_of_fruits SUBMULTISET OF g.list_of_fruits
            AND f.name <> g.name )
WHERE  f.name = 'Alice';
WITH grouped AS (
  SELECT name,
        CAST( COLLECT( fruit ) AS VARCHAR2s_Table ) AS list_of_fruits
  FROM fruits
  GROUP BY name
)
SELECT name
FROM   grouped
WHERE  name <> 'Alice'
AND    ( SELECT list_of_fruits FROM grouped WHERE name = 'Alice' )
       SUBMULTISET OF list_of_fruits ;
WITH match_by_user AS (
  SELECT DISTINCT
         name,
         fruit
  FROM   fruits
  WHERE  name = 'Alice'
)
SELECT f.name
FROM   fruits f
       INNER JOIN
       match_by_user m
       ON (     f.fruit = m.fruit
            AND f.name  <> m.name )
GROUP BY f.name
HAVING COUNT( DISTINCT f.fruit ) = ( SELECT COUNT(1) FROM match_by_user );