查询返回重复项

时间:2016-01-30 17:17:27

标签: sql sql-server tsql sql-server-2005

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语句多次返回相同的结果。如果我有1条记录,结果会显示3次。如果我将@BillNo=1传递给该过程,则它应仅返回 一行 ,但会返回3行,这些行相同。

2 个答案:

答案 0 :(得分:2)

重复项来自以下三种情况之一(或它们的组合):

  • CompanyInfo 时有多条记录(如3条记录)。
  • tblQuickBillLabor.BillNo 有重复项时;
  • tblQuickBillParts.BillNo 有重复项时;

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

但是,由于您在查询中根本不使用表 CompanyInfo 中的值,因此您应该以任何方式删除查询的SELECT BillNo, BillDate, CustomerName, Address, CustomerId, BillLaborAmt, BillPartAmt, ServTaxAmt, VatAmt, BillNetAmt, FROM dbo.tblQuickBillMain WHERE BillNo=@BillNo ORDER BY CustomerName 部分:除非您在WHERE列表中实际包含该表中的列,否则它没有用处。删除它可能已经完全解决了您的问题。

但是,表格名称 tblQuickBillParts 强烈建议您在同一 BillNo 中拥有多条记录该表格,否则您不会将其称为 零件 复数形式。表格 tblQuickBillLabor 也是如此。

要解决由 tblQuickBillLabor.BillNo tblQuickBillParts.BillNo 加入而导致的潜在问题,请参阅以下解决方案:

解决方案A:不要连接表

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

BillNo IN (sub query)

这样你就不会得到重复,但你也会得到 tblQuickBillLabor.BillNo tblQuickBillParts中没有相应记录的记录.BillNo 即可。如果需要匹配,请检查下一个解决方案。

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

如果你想要加入 tblQuickBillLabor.BillNo tblQuickBillParts.BillNo 的原因确保这些表格中至少有一个匹配的记录,然后以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 的形式使用SELECT DISTINCT条件:

SELECT

请注意,使用此SQL语句,您无需使用 A P 对表进行别名, L ,因为没有歧义。

解决方案C:错误{{1}}

从结果集中删除重复项的简单但又懒惰且不可取的方法是在{{1}}之后的Here's a list

使用此“解决方案”,您并没有真正找到问题的根源;你只需忽略它并要求一个非重复的结果集。因此,我建议您选择最适合您要求的解决方案A或B.

答案 1 :(得分:0)

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