这是三张桌子 表格:车辆类型
VehTypID Name
1 Car
2 Public Bus
3 Ambulance
4 Trucks
5 Auto
表:服务
VehTypID Name
1 Towing Alert
1 Over Speed Alert
3 Location
4 Odo Meter
4 Speed Limit
4 Fuel Limit
4 SOS
4 Emergency Control
表:NotificationAndReports
VehTypID Name
1 Popup
1 Email
1 SMS
1 WhatsApp
2 Digital Status
4 Email Reports
4 Daily Summary Reports
4 Live Tracking
,预期结果是 预期结果
Vehicle Types Services NotificationAndReports
Car Towing Alert Popup
null Over Speed Alert Email
null null SMS
null null WhatsApp
Public Bus null Digital Status
Ambulance Location null
Trucks Odo Meter Email Reports
null Speed Limit Daily Summary Reports
null Fuel Limit Live Tracking
null SOS null
null Emergency Control null
Auto null null
我使用左联接获取数据,但没有给出以上结果,而是返回了多个值。
答案 0 :(得分:1)
尝试一下:-
CREATE TABLE #VehicleTypes(
VehTypID BIGINT,
Name NVARCHAR(max))
INSERT INTO #VehicleTypes
SELECT * FROM (
SELECT 1 as bbbb ,'Car' as aaaa union all
SELECT 2 as bbbb,'Public Bus' as aaaa union all
select 3 as bbbb, 'Ambulance' as aaaa union all
select 4 as bbbb, 'Trucks' as aaaa union all
select 5 as bbbb, 'Auto' as aaaa ) AS a
CREATE TABLE #Services
(
VehTypID BIGINT,
Name NVARCHAR(max))
INSERT INTO #Services
SELECT * FROM (
select 1 as bbbb, 'Towing Alert' as aaaa union all
select 1 as bbbb, 'Over Speed Alert' as aaaa union all
select 3 as bbbb, 'Location' as aaaa union all
select 4 as bbbb, 'Odo Meter' as aaaa union all
select 4 as bbbb, 'Speed Limit' as aaaa union all
select 4 as bbbb, 'Fuel Limit' as aaaa union all
select 4 as bbbb, 'SOS' as aaaa union all
select 4 as bbbb, 'Emergency CONTROL' as aaaa ) AS a
CREATE TABLE #NotificationAndReports
(
VehTypID BIGINT,
Name NVARCHAR(max))
INSERT INTO #NotificationAndReports
SELECT * FROM (
select 1 as bbbb , 'Popup' as aaaa union all
select 1 as bbbb , 'Email' as aaaa union all
select 1 as bbbb , 'SMS' as aaaa union all
select 1 as bbbb , 'WhatsApp' as aaaa union all
select 2 as bbbb , 'Digital Status' as aaaa union all
select 4 as bbbb , 'Email Reports' as aaaa union all
select 4 as bbbb , 'Daily Summary Reports' as aaaa union all
select 4 as bbbb , 'Live Tracking' as aaaa ) AS a
SELECT ROW_NUMBER()OVER (ORDER BY ( SELECT 1 )) AS rno, ROW_NUMBER()OVER (PARTITION BY #VehicleTypes.VehTypID ORDER BY ( SELECT 1 )) AS PrntID,
ROW_NUMBER()OVER (PARTITION BY #Services.Name ORDER BY ( SELECT 1 )) AS ChildRn,
#VehicleTypes.Name AS VehicleTypes,#Services.Name AS Services,#NotificationAndReports.Name AS NotificationAndReports
INTO #temp
FROM #VehicleTypes
RIGHT JOIN #Services
ON #Services.VehTypID = #VehicleTypes.VehTypID
LEFT JOIN #NotificationAndReports
ON #NotificationAndReports.VehTypID = #VehicleTypes.VehTypID
ORDER BY #VehicleTypes.VehTypID
SELECT CASE WHEN PrntID = 1 THEN VehicleTypes ELSE NULL END AS VehicleTypes,CASE WHEN ChildRn = 1 THEN Services ELSE NULL END AS Services,NotificationAndReports
FROM #temp ORDER BY rno
DROP TABLE #NotificationAndReports,#Services,#VehicleTypes,#temp`
答案 1 :(得分:0)
您无法摆脱结果中的多个值。由于使用“关系”的关系数据库。想象一下,您摆脱了重复项,但是例如预期的行
"null, null, SMS"
没有对类型或服务的引用。您可能可以检查上一行,但是在关系数据库中,每一行都必须具有所有信息,因为行是相等的,并且行的顺序不应该影响结果(就关系代数而言)。
但是,如果您使用的数据库支持 arrays (例如Postgresql),则可以使用数组来简化查询。使用这样的SQL
select t.Name,
(select array(select s.Name from Services as s where s.VehTypID = t.VehTypID)) as "Services",
(select array(select r.Name from Reports as r where r.VehTypID = t.VehTypID)) as "Reports"
from Types as t
您将得到这样的结果
| name | Services | Reports |
| ---------- | ------------------------------------------------------ | ------------------------------------------------- |
| Car | Towing Alert,Over Speed Alert | Popup,Email,SMS,WhatsApp |
| Public Bus | | Digital Status |
| Ambulance | Location | |
| Trucks | Odo Meter,Speed Limit,Fuel Limit,SOS,Emergency Control | Email Reports,Daily Summary Reports,Live Tracking |
| Auto | | |
答案 2 :(得分:0)
/* Works In Microsoft SQL Server */
CREATE TABLE #VehicleTypes
(
VehTypID BIGINT ,
Name NVARCHAR(MAX)
);
INSERT INTO #VehicleTypes
SELECT *
FROM (
SELECT 1 AS bbbb ,
'Car' AS aaaa
UNION ALL
SELECT 2 AS bbbb ,
'Public Bus' AS aaaa
UNION ALL
SELECT 3 AS bbbb ,
'Ambulance' AS aaaa
UNION ALL
SELECT 4 AS bbbb ,
'Trucks' AS aaaa
UNION ALL
SELECT 5 AS bbbb ,
'Auto' AS aaaa
) AS a;
CREATE TABLE #Services
(
VehTypID BIGINT ,
Name NVARCHAR(MAX)
);
INSERT INTO #Services
SELECT *
FROM (
SELECT 1 AS bbbb ,
'Towing Alert' AS aaaa
UNION ALL
SELECT 1 AS bbbb ,
'Over Speed Alert' AS aaaa
UNION ALL
SELECT 3 AS bbbb ,
'Location' AS aaaa
UNION ALL
SELECT 4 AS bbbb ,
'Odo Meter' AS aaaa
UNION ALL
SELECT 4 AS bbbb ,
'Speed Limit' AS aaaa
UNION ALL
SELECT 4 AS bbbb ,
'Fuel Limit' AS aaaa
UNION ALL
SELECT 4 AS bbbb ,
'SOS' AS aaaa
UNION ALL
SELECT 4 AS bbbb ,
'Emergency CONTROL' AS aaaa
) AS a;
CREATE TABLE #NotificationAndReports
(
VehTypID BIGINT ,
Name NVARCHAR(MAX)
);
INSERT INTO #NotificationAndReports
SELECT *
FROM (
SELECT 1 AS bbbb ,
'Popup' AS aaaa
UNION ALL
SELECT 1 AS bbbb ,
'Email' AS aaaa
UNION ALL
SELECT 1 AS bbbb ,
'SMS' AS aaaa
UNION ALL
SELECT 1 AS bbbb ,
'WhatsApp' AS aaaa
UNION ALL
SELECT 2 AS bbbb ,
'Digital Status' AS aaaa
UNION ALL
SELECT 4 AS bbbb ,
'Email Reports' AS aaaa
UNION ALL
SELECT 4 AS bbbb ,
'Daily Summary Reports' AS aaaa
UNION ALL
SELECT 4 AS bbbb ,
'Live Tracking' AS aaaa
) AS a;
/*Way 1 */
SELECT CASE WHEN LAG(#VehicleTypes.Name, 1, 0) OVER ( ORDER BY #VehicleTypes.VehTypID ) = '0'
OR LAG(#VehicleTypes.Name, 1, 0) OVER ( ORDER BY #VehicleTypes.VehTypID ) <> #VehicleTypes.Name THEN
#VehicleTypes.Name
ELSE NULL
END AS VehicleName ,
CASE WHEN LAG(#Services.Name, 1, 0) OVER ( ORDER BY #VehicleTypes.VehTypID ) = '0'
OR LAG(#Services.Name, 1, 0) OVER ( ORDER BY #VehicleTypes.VehTypID ) <> #Services.Name THEN
#Services.Name
ELSE NULL
END AS ServicesName ,
#VehicleTypes.VehTypID ,
#Services.VehTypID ,
#NotificationAndReports.VehTypID ,
#NotificationAndReports.Name
FROM #VehicleTypes
RIGHT JOIN #Services ON #Services.VehTypID = #VehicleTypes.VehTypID
LEFT JOIN #NotificationAndReports ON #NotificationAndReports.VehTypID = #VehicleTypes.VehTypID;
/*Way 2 */
SELECT CASE WHEN ROW_NUMBER() OVER ( PARTITION BY #VehicleTypes.Name
ORDER BY #VehicleTypes.VehTypID
) = 1 THEN #VehicleTypes.Name
ELSE NULL
END AS VehicleName ,
CASE WHEN ROW_NUMBER() OVER ( PARTITION BY #Services.Name
ORDER BY #VehicleTypes.VehTypID
) = 1 THEN #Services.Name
ELSE NULL
END AS ServicesName ,
#VehicleTypes.VehTypID ,
#Services.VehTypID ,
#NotificationAndReports.VehTypID ,
#NotificationAndReports.Name
FROM #VehicleTypes
RIGHT JOIN #Services ON #Services.VehTypID = #VehicleTypes.VehTypID
LEFT JOIN #NotificationAndReports ON #NotificationAndReports.VehTypID = #VehicleTypes.VehTypID;
DROP TABLE #VehicleTypes ,
#NotificationAndReports ,
#Services;