Sql 选择忠诚于一家公司的所有客户?

Sql 选择忠诚于一家公司的所有客户?,sql,select,join,Sql,Select,Join,我有桌子: TABLE | COLUMNS ----------+---------------------------------- CUSTOMER | C_ID, C_NAME, C_ADDRESS SHOP | S_ID, S_NAME, S_ADDRESS, S_COMPANY ORDER | S_ID, C_ID, O_DATE 我想选择只从一家公司的商店订购的所有客户的id-‘三星’(‘LG’、‘HP’,……其实并不重要,它是动态的) 我只有一个

我有桌子:

TABLE     | COLUMNS
----------+----------------------------------
CUSTOMER  |  C_ID, C_NAME, C_ADDRESS
SHOP      |  S_ID, S_NAME, S_ADDRESS, S_COMPANY
ORDER     |  S_ID, C_ID, O_DATE
我想选择只从一家公司的商店订购的所有客户的id-‘三星’(‘LG’、‘HP’,……其实并不重要,它是动态的)

我只有一个解决方案,但我认为它很难看:

( SELECT DISTINCT c_id FROM order JOIN shop USING(s_id) WHERE s_company = "Samsung" )
EXCEPT 
( SELECT DISTINCT c_id FROM order JOIN shop USING(s_id) WHERE s_company != "Samsung" );
相同的SQL查询,但运算符相反。难道没有任何聚合方法可以更好地解决此类查询吗

我的意思是,可能会有数以百万计的订单(我没有真正的订单,我有一些更经常发生的事情)

选择数千份订单,然后将其与拥有不同公司的数十万份订单进行比较是否有效?我知道,它比较排序的东西,所以它是
O(m+n+sort(n)+sort(m))
。但这对于数百万张唱片来说仍然是巨大的,或者不是

还有一个问题。如何选择所有客户值(名称、地址)。我怎样才能加入他们,我能做什么

SELECT CUSTOMER.* FROM CUSTOMER JOIN ( (SELECT...) EXCEPT (SELECT...) ) USING (C_ID);

免责声明:这个问题不是家庭作业。这是为考试做准备,希望事情更有效。我的答案会在考试时被接受,但我喜欢有效的编程。

我喜欢使用
分组方式和
包含
子句来处理这类问题。您可以使用以下方法获取客户列表:

select o.c_id
from orders o join
     shops s
     on o.s_id = o.s_id
group by c_id
having min(s.s_company) = max(s.s_company);
如果您关心特定的公司,那么:

having min(s.s_company) = max(s.s_company) and
       max(s.s_company) = 'Samsung'
如果需要完整的客户信息,可以重新加入customers表


除了
版本之外,这是否比
版本更有效,需要在您的系统上进行测试。

我喜欢使用
分组方式和
having
子句来处理这类问题。您可以使用以下方法获取客户列表:

select o.c_id
from orders o join
     shops s
     on o.s_id = o.s_id
group by c_id
having min(s.s_company) = max(s.s_company);
如果您关心特定的公司,那么:

having min(s.s_company) = max(s.s_company) and
       max(s.s_company) = 'Samsung'
如果需要完整的客户信息,可以重新加入customers表


除了
版本之外,这是否比
版本更有效还需要在您的系统上进行测试。

如果查询不使用诸如Min和Max之类的聚合函数,效果如何

select  C_ID, S_ID
from    shop
group by C_ID, S_ID;
现在我们有了一份清晰的客户名单和他们购物的所有公司。忠诚的客户将是列表中只出现一次的客户

select  C_ID
from    Q1
group by C_ID
having count(*) = 1;
返回第一个查询以获取公司id:

with
Q1 as(
  select  C_ID, S_ID
  from    shop
  group by C_ID, S_ID
),
Q2 as(
  select  C_ID
  from    Q1
  group by C_ID
  having count(*) = 1
)
select  Q1.C_ID, Q1.S_ID
from    Q1
join    Q2
    on  Q2.C_ID = Q1.C_ID;

现在你有了一个忠诚客户的列表,每个人都忠诚于一家公司。

一个不使用像Min和Max这样的聚合函数的查询怎么样

select  C_ID, S_ID
from    shop
group by C_ID, S_ID;
现在我们有了一份清晰的客户名单和他们购物的所有公司。忠诚的客户将是列表中只出现一次的客户

select  C_ID
from    Q1
group by C_ID
having count(*) = 1;
返回第一个查询以获取公司id:

with
Q1 as(
  select  C_ID, S_ID
  from    shop
  group by C_ID, S_ID
),
Q2 as(
  select  C_ID
  from    Q1
  group by C_ID
  having count(*) = 1
)
select  Q1.C_ID, Q1.S_ID
from    Q1
join    Q2
    on  Q2.C_ID = Q1.C_ID;

现在,您有了一个忠诚客户列表,每个人都忠于一家公司。

通过使用COUNT(不同的S_ID)=1组合,一个客户可以从更多的商店购买,但可以从具有相同公司名称“S_company”的商店购买。甚至我如何向查询中添加特定的公司<代码>其中s_company=“LG”按c_id分组,计数(不同的s_company)=1
-这将始终是真的,因为我只从我想要的公司中选择行。如果没有
WHERE
,我可以选择忠诚于一家公司的客户,但不能选择特定的客户。虽然这对您的问题不重要,但也可以为您正在使用的DBMS(Postgres、Oracle、SQL Server…)添加相应的标记。标准SQL->not specific DBMS.GROUP与计数(不同的s_ID)结合使用=1一个客户可以从更多的商店购买,但可以从具有相同公司名称“S_company”的商店购买。甚至我如何向查询中添加特定的公司<代码>其中s_company=“LG”按c_id分组,计数(不同的s_company)=1
-这将始终是真的,因为我只从我想要的公司中选择行。如果没有
WHERE
,我可以选择忠诚于一家公司的客户,但不能选择特定的客户。虽然对您的问题不重要,但最好也为您正在使用的DBMS(Postgres、Oracle、SQL Server…)添加相应的标签标准SQL->非特定DBMS.Wow。聪明的。若只从一家公司购买,那个么它是特定客户按字母顺序排列的公司列表中的第一个也是最后一个。如果只从特定的公司中选择,那么我可以比较列表中的第一个/最后一个公司。还有一个问题。在第一个例子中,如果我想选择客户忠诚的公司名称。我怎么做?我的意思是,我不能只根据“c_id”进行分组,因为s.s_公司不可能是相同的。通过
拥有
子句,它将是,但SQL server无法知道它将只选择一个公司,即
min(a)=max(a)
->
single(a)
@Miro。我不明白你评论中的问题。你说的“忠诚”是什么意思?也许这应该是一个单独的问题。哇。聪明的。若只从一家公司购买,那个么它是特定客户按字母顺序排列的公司列表中的第一个也是最后一个。如果只从特定的公司中选择,那么我可以比较列表中的第一个/最后一个公司。还有一个问题。在第一个例子中,如果我想选择客户忠诚的公司名称。我怎么做?我的意思是,我不能只根据“c_id”进行分组,因为s.s_公司不可能是相同的。通过
拥有
子句,它将是,但SQL server无法知道它将只选择一个公司,即
min(a)=max(a)
->
single(a)
@Miro。我不明白你评论中的问题。你说的“忠诚”是什么意思?也许这应该是一个单独的问题。很好的解决方案。然而,
min
/
max
解决方案非常短。很好的解决方案。但是,
min
/
max
解决方案的时间非常短。