left join with subquery with one result

left join with subquery with one result

这里有一个查询:

SELECT 
k.[mg_KarId] AS [mg_KarId],
k.[SymKar] AS [SymKar],
k.[OpiKar] AS [OpiKar],
k.[Status] AS [Status],
kmlg.SymLok AS Lok_GLS1,
kmlk.SymLok AS Lok_KRS1,
kmlw.SymLok AS Lok_WLS1

FROM dbo.[mg_vv_Kar_All] AS k WITH (NOLOCK)

LEFT JOIN (
    SELECT kml.SymKar, kml.SymLok
    FROM dbo.mg_KarMagLok kml
    WHERE kml.Mag LIKE 'GLS1' 
    ) kmlg ON k.SymKar = kmlg.SymKar
LEFT JOIN (
    SELECT kml.SymKar, kml.SymLok
    FROM dbo.mg_KarMagLok kml
        WHERE kml.Mag LIKE 'KRS1'
        ) kmlk ON k.SymKar = kmlk.SymKar    
LEFT JOIN (
    SELECT kml.SymKar, kml.SymLok
    FROM dbo.mg_KarMagLok kml
        WHERE kml.Mag LIKE 'WLS1'
        ) kmlw ON k.SymKar = kmlw.SymKar
WHERE k.Status <> 'W'
and k.SymKar = '0006438';

它给了我八行 - 来自每个 LEFT JOIN (2 * 2 * 2) 的 2 行:

2002111576  0006438 CUKIER  A   R03-C-05    S07-A-08    WR03-19-01
2002111576  0006438 CUKIER  A   R03-C-05    S07-A-08    WR04-20-50
2002111576  0006438 CUKIER  A   R03-C-05    S07-A-09    WR03-19-01
2002111576  0006438 CUKIER  A   R03-C-05    S07-A-09    WR04-20-50
2002111576  0006438 CUKIER  A   R04-A-02    S07-A-08    WR03-19-01
2002111576  0006438 CUKIER  A   R04-A-02    S07-A-08    WR04-20-50
2002111576  0006438 CUKIER  A   R04-A-02    S07-A-09    WR03-19-01
2002111576  0006438 CUKIER  A   R04-A-02    S07-A-09    WR04-20-50

我只需要一行 - 无论是哪一行。我尝试将 LEFT JOIN 中的子查询修改为:

SELECT TOP 1 kml.SymKar, kml.SymLok
    FROM dbo.mg_KarMagLok kml
    WHERE kml.Mag LIKE 'GLS1'

但它在 Lok_GLS1 列的主查询中给了我 NULL。 我该如何解决这个问题?

这个子查询:

SELECT TOP 1 kml.SymKar, kml.SymLok
FROM dbo.mg_KarMagLok kml
WHERE kml.Mag LIKE 'GLS1'

returns 来自 dbo.mg_KarMagLokTOP 1 记录 SymKar 字段上的 dbo.[mg_vv_Kar_All] 的相关性无关 .因此,最有可能的是第一个 LEFT JOIN 失败,导致 kmlg.SymLok(别名 Lok_GLS1)成为 NULL.

如果您想在子查询中使用 TOP 1,您必须将 LEFT JOIN 替换为 OUTER APPLY:

OUTER APPLY (
    SELECT TOP 1 kml.SymLok
    FROM dbo.mg_KarMagLok kml
    WHERE kml.Mag LIKE 'GLS1' AND k.SymKar = kmlg.SymKar AND
          kml.SymLok IS NOT NULL       
) kmlg(Lok_GLS1) 
SELECT 
k.[mg_KarId] AS [mg_KarId],
k.[SymKar] AS [SymKar],
k.[OpiKar] AS [OpiKar],
k.[Status] AS [Status],
(
    SELECT TOP 1 kml.SymLok
    FROM dbo.mg_KarMagLok kml
    WHERE kml.Mag LIKE 'GLS1' 
    AND kml ON k.SymKar = kmlg.SymKar
) ,
(
    SELECT TOP 1 kml.SymLok
    FROM dbo.mg_KarMagLok kml
    WHERE kml.Mag LIKE 'KRS1'
    AND k.SymKar = kml.SymKar
) ,
(
    SELECT TOP 1 kml.SymLok
    FROM dbo.mg_KarMagLok kml
    WHERE kml.Mag LIKE 'WLS1'
    AND kmlw ON k.SymKar = kml.SymKar  
) 
FROM dbo.[mg_vv_Kar_All] AS k WITH (NOLOCK)
WHERE k.Status <> 'W'
and k.SymKar = '0006438';

你可以考虑使用子查询,避免 3 次连接

如果您真的不关心结果集中的最后三列,为什么不这样做:

SELECT TOP 1
k.[mg_KarId] AS [mg_KarId],
k.[SymKar] AS [SymKar],
k.[OpiKar] AS [OpiKar],
k.[Status] AS [Status]

FROM dbo.[mg_vv_Kar_All] AS k WITH (NOLOCK)
WHERE k.Status <> 'W'
and k.SymKar = '0006438';

如果要解决聚合问题,可以对数据集进行分组。 不要使用 TOP 关键字,而是编写如下查询:

SELECT kml.SymKar, kml.SymLok
FROM dbo.mg_KarMagLok kml
WHERE kml.Mag LIKE 'GLS1'
group by kml.SymKar, kml.SymLok