SQL查询中的WHERE子句

时间:2016-12-10 13:49:31

标签: sql sql-server

我认为此查询发生的情况是,如果与产品关联的GenericAttribute表中没有记录,则不显示该产品。请参阅WHERE子句中的以下行:“AND GenericAttribute.KeyGroup ='Product'”

是否有一种方法可以重写,以便在GenericAttribute表中没有相关记录时忽略WHERE的那部分?

另外,查看我的ORDER BY子句,如果Pvl_AdDates表中没有关联记录,那么产品表中的记录是否仍会显示?

谢谢!

autoItSetOption("MouseClickDelay", 10) ;10 milliseconds

2 个答案:

答案 0 :(得分:2)

我强烈建议您不要混用left joinright join。我已经编写了很多SQL查询,并且在必要时无法想到这一点。

事实上,只要坚持left join

如果您想要所有产品(或至少所有产品未通过where子句过滤掉),请从产品表开始,然后从那里开始:

FROM Products p LEFT JOIN
     Product_Category_Mapping pcm
     ON pcm.ProductId = p.Id LEFT JOIN
     Pvl_AdDates ad
     ON ad.ProductId = p.id LEFT JOIN
     Pvl_Urls u
     ON u.ProductId = p.id LEFT JOIN
     GenericAttribute ga
     ON ga.EntityId = p.id LEFT JOIN
     Address a
     ON a.Id = convert(int, ga.Value) 

请注意,我添加了表别名。这些使查询更容易编写和阅读。

我会谨慎一点。看起来您正在组合不同维度的数据。您可能会获得每个维度的维度属性的笛卡尔积。也许这就是你想要的,或WHERE子句处理额外的行。

答案 1 :(得分:1)

是在外连接的on条件中对外连接外侧的表放置约束(限制),而不是在where子句中。在评估外连接之前不评估和应用where子句的条件,因此在外表中没有记录的情况下,谓词将为false并且将消除整行,从而撤消外部。在连接期间评估连接中的条件,然后再将内侧的行添加回来,因此结果集仍将包含它们。

其次,格式化格式,格式化!坚持一个连接方向(左边更容易)并使用别名表格名称!

SELECT DISTINCT m.CategoryId, p.Id, 
    p.Name, p.ShortDescription, d.Caption, d.EventDateTime, 
    convert(varchar(25), d.EventDateTime, 120) TheDate, 
    d.DisplayOrder, u.URL, a.FirstName, a.LastName, 
    a.Email, a.Company, a.City, a.Address1, a.Address2, 
    a.ZipPostalCode, a.PhoneNumber 
FROM Product_Category_Mapping m
    left join Product p on p.Id = m.ProductId 
        and p.Published=1 
        and p.Deleted=0 
        and p.AvailableStartDateTimeUtc <= getdate() 
        and p.AvailableEndDateTimeUtc >= getdate() 
    left join Pvl_AdDates d ON d.ProductId = p.Id 
    left join Pvl_Urls u ON u.ProductId = p.Id
    left join GenericAttribute g ON g.EntityId = p.Id
        and g.KeyGroup = 'Product'
    left join [Address] a ON a.Id = convert(int, g.Value) 
WHERE m.CategoryId=12                  
ORDER BY d.EventDateTime DESC, p.Id, d.DisplayOrder