Warning: file_get_contents(/data/phpspider/zhask/data//catemap/7/sql-server/25.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
在SQLServer中使用内部联接检索时如何避免重复记录_Sql_Sql Server_Database_Stored Procedures_Inner Join - Fatal编程技术网

在SQLServer中使用内部联接检索时如何避免重复记录

在SQLServer中使用内部联接检索时如何避免重复记录,sql,sql-server,database,stored-procedures,inner-join,Sql,Sql Server,Database,Stored Procedures,Inner Join,这是我的存储程序,用于打印。我面临的问题,因为我得到的记录两倍于他们的存在由于评论加入。我想得到下面提到的输出。我是DB的新手。在此方面的帮助将不胜感激 DECLARE @path AS VARCHAR(100) SET @path = N'~/BillAttachments/166/' DECLARE @billID AS INT SET @billID = 166 SELECT bh.billID,bh.statusID,bh.modifiedOn,bs.statusName FROM d

这是我的存储程序,用于打印。我面临的问题,因为我得到的记录两倍于他们的存在由于评论加入。我想得到下面提到的输出。我是DB的新手。在此方面的帮助将不胜感激

DECLARE @path AS VARCHAR(100)
SET @path = N'~/BillAttachments/166/'
DECLARE @billID AS INT
SET @billID = 166

SELECT bh.billID,bh.statusID,bh.modifiedOn,bs.statusName
FROM dbo.eInvoice_tbl_billHistory AS bh
--INNER JOIN dbo.eInvoice_tbl_billAttachment AS ba ON bh.billID = ba.billID
--INNER JOIN dbo.eInvoice_tbl_billAttachment AS ba ON ba.billID = bh.billID
INNER JOIN dbo.eInvoice_tbl_billStatus AS bs ON bh.statusID = bs.statusID
WHERE bh.billID=@billID;
当我试图从所需的表中获取这些列时

ba.attachmentID ,
        @path + ba.fileName AS asad ,
        ba.attachmentDescription ,
        ba.billAttachmentStatus,
输出为:

166 3   2015-11-30 11:44:18.663 Approve
166 3   2015-11-30 11:44:18.663 Approve
166 5   2015-11-30 11:44:42.600 Paid
166 5   2015-11-30 11:44:42.600 Paid
但期望的产出是:

166 3   2015-11-30 11:44:18.663 Approve
166 5   2015-11-30 11:44:42.600 Paid
使用:

指定结果集中只能显示唯一的行

另一种方法是使用
分组方式

SELECT bh.billID,bh.statusID,bh.modifiedOn,bs.statusName 
FROM dbo.eInvoice_tbl_billHistory AS bh
--INNER JOIN dbo.eInvoice_tbl_billAttachment AS ba ON bh.billID = ba.billID
--INNER JOIN dbo.eInvoice_tbl_billAttachment AS ba ON ba.billID = bh.billID
INNER JOIN dbo.eInvoice_tbl_billStatus AS bs ON bh.statusID = bs.statusID
WHERE bh.billID=@billID
GROUP BY bh.billID,bh.statusID,bh.modifiedOn,bs.statusName;

如果您的规则变得更复杂,您希望使用CTE和排名函数保留哪一行,则采用另一种方法:

WITH CTE AS
(
    SELECT bh.billID, 
           bh.statusID, 
           bh.modifiedOn, 
           bs.statusName,
           rn = ROW_NUMBER() OVER() (PARTITION BY bh.billID, bh.statusID ORDER BY bh.modifiedOn ASC)
    FROM   dbo.eInvoice_tbl_billHistory AS bh 
           INNER JOIN dbo.eInvoice_tbl_billStatus AS bs 
                   ON bh.statusID = bs.statusID 
    WHERE  bh.billID = @billID; 
)
SELECT billID, statusID, modifiedOn, statusName
FROM CTE 
WHERE RN = 1

在本例中,我根据
modifiedOn
datetime保留每个
BillId
+
StatusID
组合的第一行。

在您的代码中,您将与eInvoice\u tbl\u billAttachment作为ba连接,但不在select语句中使用它。您提到这似乎是导致重复行的原因,因此我猜该表中有2行的billID=166

那你为什么要加入这张桌子?如果您只想从eInvoice_tbl_billHistory返回在ba中至少有一行的行作为bh,则可以使用exists语句:

DECLARE @path AS VARCHAR(100)
SET @path = N'~/BillAttachments/166/'
DECLARE @billID AS INT
SET @billID = 166

SELECT bh.billID,bh.statusID,bh.modifiedOn,bs.statusName
FROM dbo.eInvoice_tbl_billHistory AS bh
INNER JOIN dbo.eInvoice_tbl_billStatus AS bs ON bh.statusID = bs.statusID
WHERE bh.billID=@billID 
AND exists (select 1 from dbo.eInvoice_tbl_billAttachment AS ba 
            where  bh.billID = ba.billID);

在选择关键字后使用Distinct关键字。

您应该调查数据,找出获得重复项的原因。虽然您可以通过修改查询来解决问题(例如,使用
选择distinct
),但您应该确保数据正确且不包含重复项。请再次查看问题,它已被修改。您还可以执行选择。。。联合相同的选择以获得不同的值。
DECLARE @path AS VARCHAR(100)
SET @path = N'~/BillAttachments/166/'
DECLARE @billID AS INT
SET @billID = 166

SELECT bh.billID,bh.statusID,bh.modifiedOn,bs.statusName
FROM dbo.eInvoice_tbl_billHistory AS bh
INNER JOIN dbo.eInvoice_tbl_billStatus AS bs ON bh.statusID = bs.statusID
WHERE bh.billID=@billID 
AND exists (select 1 from dbo.eInvoice_tbl_billAttachment AS ba 
            where  bh.billID = ba.billID);