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

Sql server 查询两个表,并根据第一个匹配项填充一列,sql-server,join,header,match,Sql Server,Join,Header,Match,这是其中一件我确信已经讨论过1000次的事情,但是我所有的搜索都没有让我明白我需要什么 两张表:分类账和患者表 我想从分类账中选择几个列,并根据两个记录匹配从患者中添加一个列。这是我写的查询,但它永远运行: SELECT ledger.OID , ledger.PATID , ledger.PROVIDERID , ledger.LTYPE , ledger.TRANDATE , ledger.ESTINS , ledger.AMOUNT

这是其中一件我确信已经讨论过1000次的事情,但是我所有的搜索都没有让我明白我需要什么

两张表:分类账和患者表

我想从分类账中选择几个列,并根据两个记录匹配从患者中添加一个列。这是我写的查询,但它永远运行:

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和join语句的情况下运行它时,我会得到40037条记录,这正是我想要的

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


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

您没有连接dbo.patient的谓词,因此您将获得交叉连接:

这应该是:

FROM    dbo.Ledger
        INNER JOIN dbo.Patient
            ON Patient.rpid = Ledger.rpid
除了连接之外,您永远不会在任何地方引用别名为LEDGE的表,因此您最好完全删除它。所以,我想你想要的是:

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);

为了避免隐式转换,我还从单引号中提取了我假定为数字常量的内容,并从以下行中删除了ledger.PATPAID“0”:

AND (ledger.ESTINS <> '0' OR ledger.AMOUNT <> '0' or ledger.PATPAID <>'0' or ledger.PATADJUST <> '0')
如果从分类账到患者之间存在一对多关系,即dbo.patient中有多行,并且只关心第一个匹配项,则需要将联接更改为,并使用TOP 1获得一行。你的标题似乎暗示你想要第一场比赛,但问题并没有解释你如何定义第一场比赛:

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);
你在找我的朋友。将连接从内部更改为左侧,您将得到结果

如果不匹配,则Patient.OID列将为NULL

是的,from子句和join子句是不正确的,这就是它永远运行的原因

将其更改为:

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

尝试了这个,它仍然永远运行-我停止了它在499802记录。谢谢您的思考。请尝试:从[exportb].[dbo].[LEDGER]账本左侧选择COUNT1,在LEDGE.rpid=patient.rpid上加入exportb.dbo.patient,不带where子句。你能在合理的时间内得到记录吗?这两个表中的记录计数是多少?你对join中使用的列有索引吗?这让我更接近了。我想我漏掉了一个重要的细节,我道歉。分类账表将有多个相同的RPID。我想查看分类账表的每一行,将其RPID与患者RPID进行比较,并在第一次点击时填充patient.OID。我认为这个解决方案贯穿了整个患者表和分类账表——当我只需要40037条记录时,它返回了133000多条记录。如果我做一个distinct,我会得到40054条记录,但这并不是我所需要的。这有意义吗>这有意义,但您如何定义首次命中?您需要为订购者提供列,以确保第一次点击是一致的。此修订版正是我所需要的GarethD-谢谢。我是一个完全不懂合法SQL查询的新手,所以我将使用这段代码,并将其分解,从中学习。我感谢您的帮助和逻辑20多年前,在ANSI-92 SQL标准中,旧样式的逗号分隔表列表样式被正确的ANSI连接语法所取代,因此不鼓励使用它。你绝对不应该把这两种风格混在一起!请看,如果共识是否定的,他们就不应该这样做!
AND (ledger.ESTINS <> '0' OR ledger.AMOUNT <> '0' or ledger.PATPAID <>'0' or ledger.PATADJUST <> '0')
WHERE   l.PATID > 0
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);
from [exportb].[dbo].[LEDGER] LEDGE
LEFT JOIN exportb.dbo.patient ON LEDGE.rpid = PATIENT.rpid