Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/oracle/10.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,我被困在这一点上,而且我对SQL还比较陌生 以下是我们得到的问题: 列出我们所有产品的产品名称和供应商ID 从多个供应商处购买(提示:您需要一个自连接和 要解决的附加内部联接,请不要忘记删除任何 重复!!) 以下是我们正在使用的表格的屏幕截图: 这就是我所拥有的……我知道这是错的。它在一定程度上起作用,只是不完全符合教授的要求 SELECT DISTINCT productname, product_vendors.vendorid FROM products INNER JOIN Prod

我被困在这一点上,而且我对SQL还比较陌生

以下是我们得到的问题:

列出我们所有产品的产品名称和供应商ID 从多个供应商处购买(提示:您需要一个自连接和 要解决的附加内部联接,请不要忘记删除任何 重复!!)

以下是我们正在使用的表格的屏幕截图:

这就是我所拥有的……我知道这是错的。它在一定程度上起作用,只是不完全符合教授的要求

SELECT DISTINCT productname, product_vendors.vendorid 
FROM products INNER JOIN Product_Vendors
ON products.PRODUCTNUMBER = PRODUCT_VENDORS.PRODUCTNUMBER
INNER JOIN vendors ON Product_Vendors.VENDORID = vendors.VENDORID
ORDER BY products.PRODUCTNAME;
教授提供的预期产出:


我同意@jarlh的观点,即额外的信息会有所帮助-例如,数据中是否有三份副本,或者只是重复,等等

这就是说,这应该是你的开始

SELECT
    c.productname   AS 'Product'
    ,a.vendorid     AS 'Vendor1'
    ,b.vendorid     AS 'Vendor2'

FROM
    product_vendors AS a
JOIN 
    product_vendors AS b
        ON 
        a.productnumber = b.productnumber
        AND a.vendorid <> b.vendorid
JOIN
    dbo.products AS c
        ON
        a.productnumber = c.productnumber
选择
c、 产品名称为“产品”
,a.vendorid为“Vendor1”
,b.vendorid为“Vendor2”
从…起
产品供应商作为
参加
产品供应商作为b
在…上
a、 productnumber=b.productnumber
和a.vendorid b.vendorid
参加
dbo.c类产品
在…上
a、 productnumber=c.productnumber
这将限制“产品供应商”的数量,仅限于供应商不匹配的产品。 从那里,您将加入到产品中,以收回产品名称


另外-在编码格式上下功夫,干净的代码让梦想成真:)

我同意@jarlh的观点,额外的信息会有所帮助-例如,数据中是否有三份副本,或者仅仅是副本,等等

这就是说,这应该是你的开始

SELECT
    c.productname   AS 'Product'
    ,a.vendorid     AS 'Vendor1'
    ,b.vendorid     AS 'Vendor2'

FROM
    product_vendors AS a
JOIN 
    product_vendors AS b
        ON 
        a.productnumber = b.productnumber
        AND a.vendorid <> b.vendorid
JOIN
    dbo.products AS c
        ON
        a.productnumber = c.productnumber
选择
c、 产品名称为“产品”
,a.vendorid为“Vendor1”
,b.vendorid为“Vendor2”
从…起
产品供应商作为
参加
产品供应商作为b
在…上
a、 productnumber=b.productnumber
和a.vendorid b.vendorid
参加
dbo.c类产品
在…上
a、 productnumber=c.productnumber
这将限制“产品供应商”的数量,仅限于供应商不匹配的产品。 从那里,您将加入到产品中,以收回产品名称


另外-在编码格式上下功夫,干净的代码让梦想成真:)

这个问题的解决方案通常是用
count OVER
对每个产品的供应商进行计数,并且只使用一个以上的产品。简单地说:

select productname, vendorid
from
(
  select 
    p.productname, 
    pv.vendorid, 
    count(*) over (partition by product) as cnt
  from products p
  join product_vendors pv using (productnumber)
)
where cnt > 1;
如果在没有窗口功能的情况下进行此操作,则一个选项是聚合产品供应商并使用此结果:

select p.productname, pv.vendorid
from
(
  select productid 
  from product_vendors
  group by productname
  having count(*) > 1
) px
join products p using (productid)
join product_vendors pv using (productid);
或者检查产品是否存在其他供应商:

select 
  p.productname, 
  pv.vendorid, 
  count(*) over (partition by product) as cnt
from products p
join product_vendors pv on pv.productnumber = p.productnumber
where exists
(
  select *
  from product_vendors other
  where other.productnumber = pv.productnumber
  and other.vendorid <> pv.vendorid
);

然而,这是一种我不推荐的方法。您可以将一个产品的所有供应商合并(例如,如果我没有弄错的话,一个产品有10个供应商,那么该产品已经有45个组合)。因此,您会创建一个大的中间结果,但随后会使用
DISTINCT
忽略大部分结果。不要那样做。请记住:
SELECT DISTINCT
通常是一个写得不好的查询的指标(即不必要的连接导致太多您实际上不感兴趣的组合)。

此问题的解决方案通常是使用
count OVER
对每个产品的供应商进行计数,并且只使用一个以上的产品。简单地说:

select productname, vendorid
from
(
  select 
    p.productname, 
    pv.vendorid, 
    count(*) over (partition by product) as cnt
  from products p
  join product_vendors pv using (productnumber)
)
where cnt > 1;
如果在没有窗口功能的情况下进行此操作,则一个选项是聚合产品供应商并使用此结果:

select p.productname, pv.vendorid
from
(
  select productid 
  from product_vendors
  group by productname
  having count(*) > 1
) px
join products p using (productid)
join product_vendors pv using (productid);
或者检查产品是否存在其他供应商:

select 
  p.productname, 
  pv.vendorid, 
  count(*) over (partition by product) as cnt
from products p
join product_vendors pv on pv.productnumber = p.productnumber
where exists
(
  select *
  from product_vendors other
  where other.productnumber = pv.productnumber
  and other.vendorid <> pv.vendorid
);

然而,这是一种我不推荐的方法。您可以将一个产品的所有供应商合并(例如,如果我没有弄错的话,一个产品有10个供应商,那么该产品已经有45个组合)。因此,您会创建一个大的中间结果,但随后会使用
DISTINCT
忽略大部分结果。不要那样做。请记住:
SELECT DISTINCT
通常是写得不好的查询的指标(即不必要的连接导致太多您实际上不感兴趣的组合)。

指定示例表数据和预期结果-以及格式良好的文本。我可能会使用COUNT()进行分组。嗨,Mike,我们只应该在这个练习中使用内部连接。这里根本不需要左连接。内部连接同一个表两次,确保不同的供应商!指定示例表数据和预期结果-以及格式良好的文本。我可能会使用COUNT()进行分组。嗨,Mike,本练习只使用内部联接。这里根本不需要左联接。内部联接同一个表两次,请确保不同的供应商!使用合适的别名会更好,例如产品的
p
,产品供应商的
v1
v2
。使用合适的别名会更好,例如产品的
p
,产品供应商的
v1
v2
。请在回答中添加说明。您的代码是什么?请在答案中添加说明。你的代码是做什么的