总结冗余SQL信息
给定(Oracle 11g): 从SQL中,是否可以在单个查询中获得按汽车和制造商列出的零件列表,而无需重复每行上的冗余数据 比如:总结冗余SQL信息,sql,oracle11g,group-by,Sql,Oracle11g,Group By,给定(Oracle 11g): 从SQL中,是否可以在单个查询中获得按汽车和制造商列出的零件列表,而无需重复每行上的冗余数据 比如: FORD ESCORT Windshield Wiper Horn Steering Wheel F-150 Windshield Wiper
FORD ESCORT Windshield Wiper
Horn
Steering Wheel
F-150 Windshield Wiper
Horn
Bed Liner
TOYOTA CAMRY Floor Mat
Door Handle
CIVIC Headlight
Horn
或者类似的事情是否需要应用程序级逻辑和/或使用报告功能。我已经尝试了许多查询,但到目前为止还没有找到任何结果。请尝试如下的
lag
函数:
WITH manufacturer AS (
SELECT 1 manufacturer_id, 'FORD' NAME FROM dual
UNION ALL SELECT 2, 'TOYOTA' FROM dual)
, CAR AS (
SELECT 1 car_id, 1 manufacturer_id, 'ESCORT' AS name FROM dual
UNION ALL SELECT 2, 1, 'F-150' FROM dual
UNION ALL SELECT 3, 2, 'CAMRY' FROM dual
UNION ALL SELECT 4, 2, 'CIVIC' FROM dual)
, part AS (
SELECT 1 AS part_id, 1 AS car_id, 'Windshield Wiper' AS part_name FROM dual
UNION ALL SELECT 2, 1, 'Horn' FROM dual
UNION ALL SELECT 3, 1, 'Steering Wheel' FROM dual
UNION ALL SELECT 4, 2, 'Windshield Wiper' FROM dual
UNION ALL SELECT 5, 2, 'Horn' FROM dual
UNION ALL SELECT 6, 2, 'Bed Liner' FROM dual
UNION ALL SELECT 7, 3, 'Floor Mat' FROM dual
UNION ALL SELECT 8, 3, 'Door Handle' FROM dual
UNION ALL SELECT 9, 4, 'Headlight' FROM dual
UNION ALL SELECT 10, 4, 'Horn' FROM dual)
SELECT case lag (m.name) over (order by p.part_id)
when m.name then null
else m.name
end as manufcturer,
case lag (c.name) over (order by p.part_id)
when c.name then null
else c.name
end as carname,
p.part_name
FROM manufacturer m INNER JOIN car c ON m.manufacturer_id = c.manufacturer_id
INNER JOIN part p ON p.car_id = c.car_ID
;
输出:
MANUFACTURER CARNAME PART_NAME
------------- --------- -----------------
FORD ESCORT Windshield Wiper
Horn
Steering Wheel
F-150 Windshield Wiper
Horn
Bed Liner
TOYOTA CAMRY Floor Mat
Door Handle
CIVIC Headlight
Horn
获得结果的自然方式是:
select m.name as manufacturer_name, c.name as car_name, p.name as part_name
from manufacturer m join
cars c
on c.manufacturer_id = m.id join
parts p
on p.car_id = c.car_id;
这将是一种表格中所有单元格都填写的格式(因此'Ford'
将位于表格的前几行)
如果您只希望每个名称的第一次出现,可以使用row\u number()
(并确保最后对结果进行排序):
+1正确使用
行号()
并澄清第一个查询。
select m.name as manufacturer_name, c.name as car_name, p.name as part_name
from manufacturer m join
cars c
on c.manufacturer_id = m.id join
parts p
on p.car_id = c.car_id;
select (case when m_seqnum = 1 then manufacturer_name else '' end) as manufacturer_name,
(case when c_seqnum = 1 then car_name else '' end) as car_name,
part_name
from (select m.name as manufacturer_name, c.name as car_name, p.name as part_name,
row_number() over (partition by m.name order by c.name, p.name) as m_seqnum,
row_number() over (partition by m.name, c.name order by p.name) as c_seqnum
from manufacturer m join
cars c
on c.manufacturer_id = m.id join
parts p
on p.car_id = c.car_id
) mcp
order by manufacturer_name, car_name, part_name;