鉴于(Oracle 11g):
MANUFACTURER
------------
ID
NAME
CARS
---------
CAR_ID
MANUFACTURER_ID
NAME
PARTS
---------
PART_ID
CAR_ID
PART_NAME
是否可以通过SQL在单个查询中获取汽车和制造商的零件清单,而无需在每行上重复冗余数据?
类似的东西:
FORD ESCORT Windshield Wiper
Horn
Steering Wheel
F-150 Windshield Wiper
Horn
Bed Liner
TOYOTA CAMRY Floor Mat
Door Handle
CIVIC Headlight
Horn
或者这样的事情需要应用程序级逻辑和/或使用报告功能。我已经尝试了很多查询,但到目前为止还没有结束。
答案 0 :(得分:1)
尝试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
答案 1 :(得分: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;
这将采用表格中填充所有单元格的格式(因此'Ford'
将位于表格的前几行中。)
如果您只想要每个名称的第一次出现,可以使用row_number()
(并确保最后对结果进行排序):
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;