我对此感到困惑,而且我对SQL相对较新。
以下是我们提出的问题:
列出我们拥有的所有产品的productname和vendorid 从多个供应商那里购买(提示:你需要一个自我加入和 另外一个INNER JOIN要解决,不要忘记删除任何内容 重复!!)
以下是我们正在使用的表格的屏幕截图:
这是我的......我知道这是错的。它在某种程度上起作用,而不是教授如何想要它。
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;
预期输出提供了教授:
答案 0 :(得分:3)
我同意@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
这将限制“产品供应商”的数量仅限于具有不匹配供应商的产品。 从那里,您将加入产品以撤回产品名称。
此外 - 编写格式,清洁代码使梦想成真:)
答案 1 :(得分:1)
此问题的解决方案通常是使用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;
如果没有窗口函数,那么一个选项就是聚合product_vendors并使用这个结果:
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
);
在这两种方法中,我都认为需要消除重复,因为products
中每个产品应该有一行,product_vendors
中每个产品和供应商应该有一行。所以我想你的教授在想的是:
select distinct
p.productname,
pv.vendorid
from products p
join product_vendors pv on pv.productnumber = p.productnumber
join product_vendors other on other.productnumber = pv.productnumber
and other.vendorid <> pv.vendorid
然而,这是我不推荐的方法。您将产品的所有供应商组合在一起(例如,对于一种产品,您只有10种供应商,如果我没有弄错的话,您只有45种产品组合)。所以你创建一个大的中间结果只是为了稍后用DISTINCT
来解散大部分结果。不要那样做。请记住:SELECT DISTINCT
通常是一个写得不好的查询的指标(即不必要的连接导致你实际上并不感兴趣的太多组合)。
答案 2 :(得分:0)
SELECT DISTINCT p.name AS product, v.id
FROM products p
INNER JOIN product_vendors pv ON p.id = pv.productid
INNER JOIN product_vendors pv2 ON pv.productid = pv2.productid AND pv.vendorid != pv2.vendorid
INNER JOIN vendors v ON v.id = pv.vendorid
ORDER BY p.name