简体   繁体   English

复杂的 Oracle SQL 查询

[英]Complex Oracle SQL query

I started learning SQL a few weeks back on my own and came upon an interesting problem that I can't seem to solve.几周前,我开始自己学习 SQL,但遇到了一个我似乎无法解决的有趣问题。 Here's the database structure:这是数据库结构:

Material (name, price, origin_country) 
Product (name, price) 
Quantities (productName, materialName, quantity)

The query should show all data of the Material that's being used in the most Products that cost 20.000 or less .该查询应显示在大多数成本为20.000 或更低的产品中使用的材料的所有数据

This is what I have so far:这是我到目前为止:

select max(count(m.name))
from Materials m
join Quantities q on (m.name=q.materialName)
join Product p on (p.name=q.productName)
where p.price < 20000
group by m.name

This, in theory, should show show the maximum number that a type of material appears in (and it indeed does so in practice).从理论上讲,这应该显示某种材料出现的最大数量(实际上确实如此)。 The problem is, I have no idea how to implement this in a way that it can show me the data from the Material table.问题是,我不知道如何以一种可以向我显示材料表中的数据的方式实现这一点。

Join the tables together, filter out the products that are too expensive and then use the COUNT analytic function to find the number of products and ORDER BY that count in descending order and return the FIRST ROW WITH TIES :将表连接在一起,过滤掉太贵的产品,然后使用COUNT分析函数查找产品数量和按降序计数的ORDER BY并返回FIRST ROW WITH TIES

SELECT M.*,
       P.name AS ProductName,
       p.Price,
       Q.Quantity,
       COUNT( DISTINCT p.ROWID ) OVER ( PARTITION BY m.ROWID ) AS num_products
FROM   Material M
       INNER JOIN Quantities Q
       ON ( m.Name = Q.MaterialName )
       INNER JOIN Product P
       ON ( Q.ProductName = P.Name )
WHERE  p.price <= 20000
ORDER BY num_products DESC
FETCH FIRST ROW WITH TIES;

(I used the ROWID pseudo-column in the count just in-case there were two products or materials with the same name then it would not group them together. If this is not going to be the case then you can just use p.Name and m.Name instead.) (我在计数中使用了ROWID伪列,以防万一有两个同名的产品或材料,那么它不会将它们组合在一起。如果不是这种情况,那么您可以使用p.Namem.Name代替。)

Which, for the sample data:其中,对于样本数据:

CREATE TABLE Material( name, price, origin_country ) AS
SELECT 'M1', 1, 'Place1' FROM DUAL UNION ALL
SELECT 'M2', 2, 'Place2' FROM DUAL UNION ALL
SELECT 'M3', 3, 'Place3' FROM DUAL;

CREATE TABLE Product (name, price) AS
SELECT 'P123', 10 FROM DUAL UNION ALL
SELECT 'P13',   8 FROM DUAL UNION ALL
SELECT 'P223',  5 FROM DUAL;

CREATE TABLE Quantities (productName, materialName, quantity) AS
SELECT 'P123', 'M1', 1 FROM DUAL UNION ALL
SELECT 'P123', 'M2', 1 FROM DUAL UNION ALL
SELECT 'P123', 'M3', 1 FROM DUAL UNION ALL
SELECT 'P13',  'M1', 1 FROM DUAL UNION ALL
SELECT 'P13',  'M3', 1 FROM DUAL UNION ALL
SELECT 'P223', 'M2', 1 FROM DUAL UNION ALL
SELECT 'P223', 'M2', 1 FROM DUAL UNION ALL
SELECT 'P223', 'M3', 1 FROM DUAL;

Outputs:输出:

\nNAME |姓名 | PRICE |价格 | ORIGIN_COUNTRY | ORIGIN_COUNTRY | PRODUCTNAME |产品名称 | PRICE |价格 | QUANTITY |数量 | NUM_PRODUCTS NUM_PRODUCTS\n:--- | :--- | ----: | ----: | :------------- | :------------- | :---------- | :---------- | ----: | ----: | -------: | -------: | -----------: -----------:\nM3 | M3 | 3 | 3 | Place3 |地点3 | P123 | P123 | 10 | 10 | 1 | 1 | 3 3\nM3 | M3 | 3 | 3 | Place3 |地点3 | P223 | P223 | 5 | 5 | 1 | 1 | 3 3\nM3 | M3 | 3 | 3 | Place3 |地点3 | P13 | P13 | 8 | 8 | 1 | 1 | 3 3\n

db<>fiddle here db<> 在这里摆弄

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM