查询返回重复项

Query returning duplicates

SET ANSI_NULLS ON
SET QUOTED_IDENTIFIER ON
GO

ALTER PROCEDURE [dbo].[PrintQuickBill](@BillNo int)
AS
SELECT      A.BillNo, 
            A.BillDate, 
            A.CustomerName, 
            A.Address, 
            A.CustomerId, 
            A.BillLaborAmt, 
            A.BillPartAmt, 
            A.ServTaxAmt, 
            A.VatAmt,
            A.BillNetAmt,
FROM        dbo.tblQuickBillMain A
INNER JOIN  [dbo].tblQuickBillLabor L
        ON  A.BillNo = L.BillNo
INNER JOIN  [dbo].tblQuickBillParts P
        ON  A.BillNo = P.BillNo
CROSS JOIN  dbo.CompanyInfo
WHERE       A.BillNo=@BillNo
ORDER BY    CustomerName

SELECT语句多次return相同的结果。如果我有 1 条记录,结果会显示 3 次。如果我将 @BillNo=1 传递给程序,它应该 return 只有 一行 但它 returns 3 行,它们是相同的。

您的查询与 table CompanyInfo 交叉连接。它返回三行,因为交叉连接 (CompanyInfo) 中的 table 有三行。您没有使用 CompanyInfo 中的任何列,因此我认为不需要该交叉连接。

重复是由以下三种情况之一(或它们的组合)造成的:

  • CompanyInfo有不止一条记录时(比如3条记录)。
  • tblQuickBillLabor.BillNo有重复时;
  • tblQuickBillParts.BillNo有重复时;

您看不到某些结果之间的差异,因为您没有显示 SELECT 列表中其他 table 的任何数据。如果您将其他 table 的列也包含在您的 SELECT 列表中,您会注意到这些列在结果中会有不同的值,其中第一组列会重复。

但是由于您在查询中根本不使用 table CompanyInfo 中的值,因此您应该以任何方式删除查询的 CROSS JOIN CompanyInfo 部分:除非您实际将 table 中的列包含在 SELECT 列表中,否则它没有任何用处。删除它可能已经完全解决了您的问题。

但是,table 名称 tblQuickBillParts 强烈建议您将拥有相同的多个记录 BillNo在那table,否则你不会叫它Parts 复数形式。 table tblQuickBillLabor.

可能也是如此

为了处理这些潜在的问题,由 tblQuickBillLabor.BillNo[= 的连接引起50=]tblQuickBillParts.BillNo,见以下解决方案:

解决方案 A:根本不加入 tables

由于您只从 tblQuickBillMain 中选择值,您最终可能根本不需要加入其他 table,只需写入:

SELECT   BillNo, 
         BillDate, 
         CustomerName, 
         Address, 
         CustomerId, 
         BillLaborAmt, 
         BillPartAmt, 
         ServTaxAmt, 
         VatAmt,
         BillNetAmt,
FROM     dbo.tblQuickBillMain
WHERE    BillNo=@BillNo
ORDER BY CustomerName

这样你不会得到重复的,但你也会得到在tblQuickBillLabor.BillNo[=91中没有对应记录的记录=] 或 tblQuickBillParts.BillNo。如果该匹配项是必需的,则检查下一个解决方案。

解决方案 B:用子查询替换联接

如果加入 tblQuickBillLabor.BillNo[= 的原因132=] 就是你要确保在那些table中至少有一条匹配的记录,那么用一个WHERE条件代替BillNo IN (sub query):

SELECT   BillNo, 
         BillDate, 
         CustomerName, 
         Address, 
         CustomerId, 
         BillLaborAmt, 
         BillPartAmt, 
         ServTaxAmt, 
         VatAmt,
         BillNetAmt,
FROM     dbo.tblQuickBillMain
WHERE    BillNo=@BillNo
AND      BillNo IN (SELECT BillNo FROM [dbo].tblQuickBillLabor)
AND      BillNo IN (SELECT BillNo FROM [dbo].tblQuickBillParts)
ORDER BY CustomerName

请注意,使用此 SQL 语句,您不需要使用 A 为您的 table 设置别名, P, L因为没有歧义。

解决方案 C:不好的 SELECT DISTINCT

从结果集中删除重复项的一种简单但懒惰且不可取的方法是 add the word DISTINCT 紧跟在单词 SELECT.

之后

用这个 "solution" 你并没有真正找到问题的根源;你只是忽略它并要求一个非重复的结果集。所以,我真的建议选择解决方案 A 或 B,以最适合您的要求为准。