SQL Server查询INNER JOIN - 缺少条目

时间:2012-01-26 12:59:54

标签: sql-server join

仅供参考 - 此查询从excel运行。我有提示字段来设置日期范围。

这是我从某人那里得到的原始工作查询:

SELECT 
   SalesInvoiceItems.FreeTextItem, SalesInvoiceItems.Product,   
   SalesInvoiceItems.ItemDescription, SalesInvoiceItems.Quantity, 
   SalesInvoiceItems.ItemValue, Customers.CustomerId, Customers.CustomerName, 
   SalesInvoices.SalesInvoiceId, SalesInvoices.EffectiveDate, Countries.CountryId, 
   SalesInvoiceItems.ItemType
FROM 
   Winman.dbo.Countries Countries, Winman.dbo.Customers Customers, 
   Winman.dbo.Products Products, Winman.dbo.SalesInvoiceItems SalesInvoiceItems, 
   Winman.dbo.SalesInvoices SalesInvoices
WHERE 
    Customers.Customer = SalesInvoices.Customer 
    AND SalesInvoiceItems.SalesInvoice = SalesInvoices.SalesInvoice 
    AND Customers.Country = Countries.Country 
    AND ((SalesInvoices.SystemType='F') 
    AND (SalesInvoiceItems.ItemType<>'T') 
    AND (SalesInvoices.EffectiveDate>=? And SalesInvoices.EffectiveDate<=?) 
    AND (SalesInvoiceItems.ItemValue<>$0))
ORDER BY 
    SalesInvoiceItems.Quantity DESC

这里的重要位是ItemType(它只能是T,不包括在内,P - 用于产品,N - 用于免费文本项目)

我需要添加表Products来检索ProductID。显然在WHERE子句中添加以下代码:

AND Products.Product = SalesInvoiceItems.Product 

将无法显示任何免费文字项目,因为它们不是产品。

所以我用JOIN重写了查询,希望能解决我的问题(提出P和N类型的条目):

SELECT 
    Products.ProductId, 
    SalesInvoiceItems.FreeTextItem, 
    SalesInvoiceItems.Product, 
    SalesInvoiceItems.ItemDescription, 
    SalesInvoiceItems.Quantity, 
    SalesInvoiceItems.ItemValue, 
    Customers.CustomerId, 
    Customers.CustomerName, 
    SalesInvoices.SalesInvoiceId, 
    SalesInvoices.EffectiveDate, 
    Countries.CountryId, 
    SalesInvoiceItems.ItemType
FROM 
    Winman.dbo.SalesInvoiceItems AS SalesInvoiceItems 
INNER JOIN 
    Winman.dbo.Products AS Products ON Products.Product = SalesInvoiceItems.Product  
INNER JOIN 
    Winman.dbo.SalesInvoices AS SalesInvoices ON SalesInvoices.SalesInvoice= SalesInvoiceItems.SalesInvoice
INNER JOIN 
    Winman.dbo.Customers AS Customers ON Customers.Customer = SalesInvoices.Customer 
INNER JOIN 
    Winman.dbo.Countries AS Countries ON  Countries.Country = Customers.Country 
WHERE 
    ((SalesInvoices.SystemType='F') 
     AND (SalesInvoiceItems.ItemType<>'T') 
     AND (SalesInvoices.EffectiveDate >= ? And SalesInvoices.EffectiveDate <= ?) 
     AND (SalesInvoiceItems.ItemValue <> $0)
    )
ORDER BY 
    SalesInvoiceItems.Quantity DESC

但这仍然充当AND - 忽略了自由文本项!我显然遗漏了一些东西..虽然免费文本项目没有ProductID,但我怎么能同时带上产品和自由文本项?

2 个答案:

答案 0 :(得分:2)

您的旧查询使用的是旧式JOIN语法。完全放弃这种隐式(内部)连接以支持显式连接是一件好事。

使用显式联接时,您现在在INNEROUTER联接(ref. MSDN)之间有选择

  

仅当两者中至少有一行时,内部联接才会返回行   与连接条件匹配的表。内连接消除了行   与另一个表中的行不匹配。 外连接,   但是,从至少一个表或视图中返回所有行   在FROM子句中提到,只要这些行符合任何WHERE或   有搜索条件。

因此,在回答您的问题时,请将INNER JOIN更改为LEFT JOIN s

答案 1 :(得分:0)

我不确定我是否理解正确,但请尝试更改:

INNER JOIN Winman.dbo.Products AS Products ON ...

为:

LEFT JOIN Winman.dbo.Products AS Products ON ...
相关问题