查询两个表并根据第一个匹配项填充一列

query for two tables and have one column populate based on first match

这是我确定已经讨论过 1000 次的事情之一,但我所有的搜索都让我无法理解我需要什么。

两个表:ledger 和 patient

我想select分类帐中的几列,并根据匹配的两条记录从患者中添加一列。这是我写的查询,但它永远只有 运行s:

SELECT 
   ledger.OID
    , ledger.PATID
    , ledger.PROVIDERID
    , ledger.LTYPE
    , ledger.TRANDATE
    , ledger.ESTINS
    , ledger.AMOUNT
    , ledger.PATPAID
    , ledger.PATADJUST
    , ledger.LEDGERID
    , ledger.TYPE2
    , ledger.rpid
    , patient.oid
    , ledger.DESCR
FROM 
    [exportb].[dbo].[LEDGER]
    , exportb.dbo.patient
INNER JOIN 
    LEDGER AS LEDGE ON LEDGE.rpid = PATIENT.rpid
WHERE 
    ledger.PATID > '0'
    AND ledger.LTYPE <> 'M'
    AND ledger.LTYPE <> 'n'
    AND (
        ledger.ESTINS <> '0'
        OR ledger.AMOUNT <> '0'
        OR ledger.PATPAID <> '0'
        OR ledger.PATADJUST <> '0'
        )

当我 运行 它没有 patient.oid 和连接语句时,我得到 40037 条记录,这正是我想要的。

我想要做的是将 patient.oid header 添加到我的结果中。我希望查询查看 LEDGER.RPID 列并匹配 PATIENT.RPID 列并为该记录填充 PATIENT.OID

我相信这很简单,但希望有人能给出一些启示!

您没有谓词连接 dbo.patient 因此获得交叉连接 (Cartesian Product):

from [exportb].[dbo].[LEDGER],exportb.dbo.patient

这应该是:

FROM    dbo.Ledger
        INNER JOIN dbo.Patient
            ON Patient.rpid = Ledger.rpid

您也永远不会在联接以外的任何地方引用别名为 LEDGE 的 table,因此您最好完全删除它。所以,我认为你追求的是:

USE Exportb;

SELECT  l.OID,
        l.PATID,
        l.PROVIDERID,
        l.LTYPE,
        l.TRANDATE,
        l.ESTINS,
        l.AMOUNT,
        l.PATPAID,
        l.PATADJUST, 
        l.LEDGERID, 
        l.TYPE2, 
        l.rpid, 
        p.oid, 
        l.DESCR 
FROM    dbo.Ledger AS l
        INNER JOIN dbo.Patient AS p
            ON p.rpid = l.rpid
WHERE   l.PATID > 0
AND     l.LType NOT IN ('M', 'n')
AND     (l.Estins <> 0 OR l.Amount <> 0 OR l.PatAdjust <> 0);

值得注意的是,我删除了交叉连接,并为 dbo.Patient 保留了一个连接。我简化了以下谓词:

AND ledger.LTYPE <> 'M' 
AND ledger.LTYPE <> 'n' 

AND     l.LType NOT IN ('M', 'n')

我还从单引号中取出了我认为是数字常量的内容以避免隐式转换,并且还从以下行中删除了 ledger.PATPAID <>'0'

AND (ledger.ESTINS <> '0' OR ledger.AMOUNT <> '0' or ledger.PATPAID <>'0' or ledger.PATADJUST <> '0')

由于谓词,该部分永远不可能为真:

WHERE   l.PATID > 0

如果您有从分类账到患者的一对多关系,即您在 dbo.patient 中有多行并且只关心第一个匹配项,那么您需要将连接更改为 APPLY 并使用 TOP 1 获取单行。你的标题似乎暗示你想要 "first match",但问题没有解释你如何定义 "first":

USE Exportb;

SELECT  l.OID,
        l.PATID,
        l.PROVIDERID,
        l.LTYPE,
        l.TRANDATE,
        l.ESTINS,
        l.AMOUNT,
        l.PATPAID,
        l.PATADJUST, 
        l.LEDGERID, 
        l.TYPE2, 
        l.rpid, 
        p.oid, 
        l.DESCR 
FROM    dbo.Ledger AS l
        CROSS APPLY
        (   SELECT  TOP 1 p.oid
            FROM    dbo.Patient AS p
            WHERE   p.rpid = l.rpid
            ORDER BY p.oid -- YOU MAY NEED TO CHANGE THIS ORDER DEPENDING ON YOUR CRITERIA
        ) AS p
WHERE   l.PATID > 0
AND     l.LType NOT IN ('M', 'n')
AND     (l.Estins <> 0 OR l.Amount <> 0 OR l.PatAdjust <> 0);

您正在寻找 LEFT JOIN 我的朋友。将联接从 INNER 更改为 LEFT,您将获得结果。

Patient.OID 将是 NULL,其中没有匹配项。

是的,from 子句和 join 子句不正确,这就是为什么它永远 运行。

改为:

from [exportb].[dbo].[LEDGER] LEDGE
LEFT JOIN exportb.dbo.patient ON LEDGE.rpid = PATIENT.rpid