如果在另一个表中找不到其ID,我该如何返回一行?

时间:2010-11-16 01:19:59

标签: sql sql-server tsql sql-server-2008

我在MS SQL 2008数据库,Listings和ListingType中有2个表,我想创建一个select语句,它将为我提供列表中所有在ListingType表中没有其ListingID的行。

我对如何开始这个陈述感到非常困惑。

示例SQL语句 - 比我解释的要多得多,但你应该能够得到我所要求的内容。

SELECT     Listing.Title, Listing.MLS, COALESCE (Pictures.PictureTH, '../default_th.jpg') AS PictureTH, COALESCE (Pictures.Picture, '../default.jpg') AS Picture, Listing.ID, 
                      Listing.Description, Listing.Lot_Size, Listing.Building_Size, Listing.Bathrooms, Listing.Bedrooms, Listing.Address1, Listing.Address2, 
                      Listing.City, Locations.Abbrev, Listing.Zip_Code, Listing.Price, Listing.Year_Built, ListingTypeMatrix.ListingTypeID
FROM         Listing INNER JOIN
                      Locations ON Listing.State = Locations.LocationID LEFT OUTER JOIN
                      ListingTypeMatrix ON Listing.ID = ListingTypeMatrix.ListingID LEFT OUTER JOIN
                      Pictures ON Listing.ID = Pictures.ListingID
WHERE     (ListingTypeMatrix.ListingTypeID = '4') AND 
          ((Pictures.ID IS NULL) OR (Pictures.ID =
                          (SELECT     MIN(ID)
                            FROM          Pictures
                            WHERE      (ListingID = Listing.ID))))

ListingTypeMatrix.ListingTypeID ='4'是我不知道要改变什么的部分,因为它没有记录。

5 个答案:

答案 0 :(得分:28)

使用NOT EXISTS

SELECT t.*
  FROM LISTING t
 WHERE NOT EXISTS(SELECT NULL
                    FROM LISTINGTYPE lt
                   WHERE lt.listingid = t.listingid)

使用NOT IN

SELECT t.*
  FROM LISTING t
 WHERE t.listingid NOT IN (SELECT lt.listingid
                             FROM LISTINGTYPE lt)

使用LEFT JOIN / IS NULL

   SELECT t.*
     FROM LISTING t
LEFT JOIN LISTINGTYPE lt ON lt.listingid = t.listingid
    WHERE lt.listingid IS NULL

摘要

Quote

  

在SQL Server中,NOT EXISTS和NOT IN谓词是搜索缺失值的最佳方法,只要两个列都是NOT NULL即可。他们通过某种反加入来制定安全有效的计划。

     

LEFT JOIN / IS NULL效率较低,因为它不会尝试跳过右表中已匹配的值,返回所有结果并将其过滤掉。

答案 1 :(得分:3)

   SELECT *
     FROM Listing l
LEFT JOIN ListingType t ON l.ID = t.ListingID
    WHERE t.ListingID IS NULL

答案 2 :(得分:3)

以下SQL将返回没有相应的ListingType记录的所有列表记录

SELECT *
FROM Listing
LEFT JOIN ListingType ON Listing.ID = ListingType.ListingID
WHERE ListingType.ID IS NULL

答案 3 :(得分:2)

假设SQL的其余部分是正确的,只需在清单TypeID上添加一个空检查:

SELECT Listing.Title, Listing.MLS, COALESCE (Pictures.PictureTH, '../default_th.jpg') AS PictureTH, COALESCE (Pictures.Picture, '../default.jpg') AS Picture, Listing.ID, Listing.Description, Listing.Lot_Size, Listing.Building_Size, Listing.Bathrooms, Listing.Bedrooms, Listing.Address1, Listing.Address2, Listing.City, Locations.Abbrev, Listing.Zip_Code, Listing.Price, Listing.Year_Built, ListingTypeMatrix.ListingTypeID 
FROM Listing 
INNER JOIN Locations ON Listing.State = Locations.LocationID 
LEFT OUTER JOIN ListingTypeMatrix ON Listing.ID = ListingTypeMatrix.ListingID 
LEFT OUTER JOIN  Pictures ON Listing.ID = Pictures.ListingID 
WHERE (ListingTypeMatrix.ListingTypeID = '4' OR ListingTypeMatrix.ListingTypeID IS NULL) AND  
          ((Pictures.ID IS NULL) OR (Pictures.ID = 
                          (SELECT     MIN(ID) 
                            FROM          Pictures 
                            WHERE      (ListingID = Listing.ID)))) 

答案 4 :(得分:2)

我认为您可能希望将ListingTypeMatrix.ListingTypeID = '4'移动到ListingTypeMatrix OUTER JOIN的ON子句。该条款看起来像这样

LEFT OUTER JOIN ListingTypeMatrix ON Listing.ID = ListingTypeMatrix.ListingID
       AND ListingTypeMatrix.ListingTypeID = '4'

并且,您将从WHERE子句中删除ListingTypeMatrix.ListingTypeID = '4' AND

此更改仅返回来自ListingTypeMatrix = 4的行,并将结果连接到查询的其余部分。 LEFT OUTER JOIN表示如果行没有出现在ListingTypeMatrix中,则不会排除Listing和Locations中的行。