我无法想象如何解决这个问题。我已经完成了简单的连接,但这在我看来很复杂。这就是我的表格
USERS
-------------------
ID | NAME | ROLE_ID
1 | BOB | 1
2 | PETE | 2
3 | JOS | 3
USER_ROLES
----------
ID | ROLE
1 | ADMIN
2 | MANAGER
3 | STAFF
CARS
---------
ID | CAR
1 | BMW
2 | MERCEDES
3 | AUDI
USER_CARS
----------------------
ID | USER_ID | CAR_ID
1 | 1 | 1
2 | 2 | 3
3 | 2 | 2
4 | 3 | 1
5 | 3 | 2
我的预期输出
Expected Output
-----------------------------------------------------
ID | NAME | ROLE_ID | ROLE | BMW | MERCEDES | AUDI
1 | BOB | 1 | ADMIN | 1 | 0 | 0
2 | PETE | 2 | MANAGER | 0 | 1 | 1
2 | JOS | 3 | STAFF | 1 | 1 | 0
汽车列中的1表示用户拥有该汽车,0表示他没有。这背后的基本逻辑是什么 - 使用循环或什么是查询的有效方法?
答案 0 :(得分:1)
您可以使用Oracle中的pivot功能实现此目的
with users(id, name, role_id) as (
select 1, 'BOB', 1 from dual union all
select 2, 'PETE', 2 from dual union all
select 3, 'JOS', 3 from dual ),
user_roles(id, role) as (
Select 1, 'ADMIN' From Dual Union All
Select 2, 'MANAGER' From Dual Union All
Select 3, 'STAFF' From Dual),
Cars(Id, Car) As (
Select 1 , 'BMW' From Dual Union All
Select 2,'MERCEDES' From Dual Union All
Select 3,'AUDI' From Dual),
User_Cars (Id,User_Id,Car_Id) As (
select 1, 1, 1 from dual union all
Select 2, 2, 3 From Dual Union All
Select 3, 2, 2 From Dual Union All
Select 4, 3, 1 From Dual Union All
SELECT 5, 3, 2 FROM DUAL)
----------------
-- End if data preparation
----------------
select * from (
SELECT u.id, u.name, u.role_id, ur.role, c.car
FROM USERS U
JOIN USER_ROLES UR ON UR.ID = U.ROLE_ID
JOIN USER_CARS UC ON UC.USER_ID = U.ID
JOIN CARS C ON C.ID = UC.CAR_ID)
PIVOT (COUNT(1) FOR CAR IN ('BMW' AS BMW, 'MERCEDES' AS MERCEDES, 'AUDI' AS AUDI))
order by 1;
输出:
| ID | NAME | ROLE_ID | ROLE | BMW | MERCEDES | AUDI |
|----|------|---------|---------|-----|----------|------|
| 1 | BOB | 1 | ADMIN | 1 | 0 | 0 |
| 2 | PETE | 2 | MANAGER | 0 | 1 | 1 |
| 3 | JOS | 3 | STAFF | 1 | 1 | 0 |
您的查询将是
select * from (
SELECT u.id, u.name, u.role_id, ur.role, c.car
FROM USERS U
JOIN USER_ROLES UR ON UR.ID = U.ROLE_ID
JOIN USER_CARS UC ON UC.USER_ID = U.ID
JOIN CARS C ON C.ID = UC.CAR_ID)
PIVOT (COUNT(1) FOR CAR IN ('BMW' AS BMW, 'MERCEDES' AS MERCEDES, 'AUDI' AS AUDI))
order by 1;
不使用pivot,您可以按照下面的说明编写
SELECT u.id,
u.name,
u.role_id,
ur.role,
count(decode(c.car, 'BMW', 1, null)) BMW,
count(decode(c.car, 'MERCEDES', 1, null)) MERCEDES,
count(decode(c.car, 'AUDI', 1, null)) AUDI
FROM USERS U
JOIN USER_ROLES UR ON UR.ID = U.ROLE_ID
JOIN USER_CARS UC ON UC.USER_ID = U.ID
JOIN CARS C ON C.ID = UC.CAR_ID
group by u.id,
u.name,
u.role_id,
ur.role
order by 1;