我如何从多个表中获得所需的结果,如下所示

时间:2018-09-29 05:05:23

标签: sql left-join

这是三张桌子 表格:车辆类型

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

我使用左联接获取数据,但没有给出以上结果,而是返回了多个值。

3 个答案:

答案 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       |                                                        |                                                   |

请参见www.db-fiddle.com

答案 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;