SQL 子选择作为字段?

Posted

技术标签:

【中文标题】SQL 子选择作为字段?【英文标题】:SQL Sub-select as field? 【发布时间】:2011-06-21 12:06:54 【问题描述】:

我有点迷路了……

我想从以下几张表中提取统一记录:UnitBuildingOwnerPicture

到目前为止,这是我的查询:

SELECT building.`Street_Address`
    , building.`Building_Name`
    , building.`Building_Type`
    , CONCAT(building.`Cross_Street_1`, ' & ', building.`Cross_Street_2`) Cross_Streets
    , building.`Cross_Street_1`
    , building.`Cross_Street_2`
    , building.`Access` Building_Access
    , owner.`Company_Name`
    , owner.`Contact_Or_Reference`
    , owner.`Landlord_Phone`
    , picture.`Path_To_Picture_On_Server`
    , picture.`Picture_Category`
    , unit.`Apartment_Number`
    , unit.`Unit_Size_Number` Size
    , unit.`Is_Doorman`
    , unit.`Is_Furnished`
    , unit.`Is_Elevator`
    , unit.`Is_Pets`
    , unit.`Is_OutdoorSpace`
    , unit.`Rent_Price`
    , unit.`Baths`
    , unit.`Access` Unit_Access
    , unit.`fourd_id`
    , unit.`Updated_Date`
    , unit.`Occupancy_Date`
    , unit.`Term`
    , unit.`Incentives`
    , unit.`Info_OutdoorSpace`
    , unit.`List_Date`
    , zone.`Description`
FROM 4D_Units unit
JOIN 4D_Building building
    ON unit.`BUILDING_RecID` = building.`fourd_id`
JOIN 4D_Zones zone
    ON building.`ZONES_RecID` = zone.`fourd_id`
LEFT JOIN 4D_Owners owner
    ON unit.`OWNER_RecID` = owner.`fourd_id`
LEFT JOIN 4D_Building_Picts picture
    ON (building.`fourd_id` = picture.`BUILDING_RecID` AND picture.`Picture_Category` = 'Front')
WHERE unit.`id` = 49901

这可以按原样正常工作,除了返回记录将永远只有记录中的“正面”图片(如果存在)。我的问题是,有几种不同类型的照片可能与退货记录相关联,包括“全景”、“室内”和“平面图”......对于picture.Picture_Category,它们都是不同的可能值。

有没有办法在返回的集合中返回这些值(如果它们存在,如上所述)而不进行单独的查询?我希望返回的集合包括(如果存在)picture.Picture_Category 的所有四个可能选项的别名值:'Front'、'Panorama'、'Interior'和'Floorplan'(与它们自己唯一的picture.Path_To_Picture_On_Server 相关联)。

这有意义吗?

【问题讨论】:

【参考方案1】:

如果我的理解正确,您希望在结果集中有 4 组图片列 - 4 个类别之一?现在你只有一个在前面,对吧?

您可以使用不同的别名和不同的连接子句多次连接到同一个表。只需加入 4D_Building_Picts 4 次,每张你想要的图片一次。

select 
    --whatever
    , pic_front.`Path_To_Picture_On_Server` AS Front_Path_To_Picture_On_Server
    , pic_panorama.`Path_To_Picture_On_Server` AS Panorama_Path_To_Picture_On_Server
    , pic_interior.`Path_To_Picture_On_Server` AS Interior_Path_To_Picture_On_Server
    , pic_floorplan.`Path_To_Picture_On_Server` AS Floorplan_Path_To_Picture_On_Server
    --whatever
FROM 4D_Units unit
JOIN 4D_Building building
    ON unit.`BUILDING_RecID` = building.`fourd_id`
JOIN 4D_Zones zone
    ON building.`ZONES_RecID` = zone.`fourd_id`
LEFT JOIN 4D_Owners owner
    ON unit.`OWNER_RecID` = owner.`fourd_id`
LEFT JOIN 4D_Building_Picts pic_front
    ON (building.`fourd_id` = pic_front.`BUILDING_RecID` AND pic_front.`Picture_Category` = 'Front')
LEFT JOIN 4D_Building_Picts pic_panorama
    ON (building.`fourd_id` = pic_panorama.`BUILDING_RecID` AND pic_panorama.`Picture_Category` = 'Panorama')
LEFT JOIN 4D_Building_Picts pic_interior
    ON (building.`fourd_id` = pic_interior.`BUILDING_RecID` AND pic_interior.`Picture_Category` = 'Interior')
LEFT JOIN 4D_Building_Picts pic_floorplan
    ON (building.`fourd_id` = pic_floorplan.`BUILDING_RecID` AND pic_floorplan.`Picture_Category` = 'Floorplan')
WHERE unit.`id` = 49901

【讨论】:

是的!我在寻找什么......但是,如果所有 4 个都存在,我会返回 4 个相同的记录而不是 1 个......我应该只是 LIMIT 1 还是有其他最佳的事情可以代替? 我忘记更改 ON 子句来引用每个子表,所以它是重复的。问题是我有building.fourd_id = picture.BUILDING_RecID 但它应该是= pic_front.BUILDING_RecID 等等。现在的版本应该只做一次 - 看看,让我知道。【参考方案2】:

我认为您需要合并功能。它需要多个字段,并返回第一个非空字段。所以像:

Select
  Coalesce(A.Panorama, A.Interior, A.Floorplan, '') as ImagePath
From
  Table A

尽管如此,您最终只会得到一个值,而这实际上可能不是您所追求的。如果您想要所有这些,我建议您使用相关子查询,如下所示:

Select
  (Select P.Path_To_Picture From 4D_Building_Picts P where P.Building_RecID = B.fourd_Id And P.Picture_Category = 'Front') as Front_Pic,
  (Select P.Path_To_Picture From 4D_Building_Picts P where P.Building_RecID = B.fourd_Id And P.Picture_Category = 'Panorama') as Panamora_Pic,
  (Select P.Path_To_Picture From 4D_Building_Picts P where P.Building_RecID = B.fourd_Id And P.Picture_Category = 'FloorPlan') as FloorPlan_Pic,
  ...
From
  4D_Building B

【讨论】:

是的,我想为每个可能的选项设置多个值。还有其他想法吗? @neezer - 我已经更新了我的选项以包含另一个选项。它使用相关子查询来检索图像路径 - 您可以将所有路径作为单独的列获取,但仍然只能为每个建筑物获取一条记录。我认为它可能符合您的需求。 感谢您的更新。我对这里的性能一无所知,所以这只是为了启发我:使用嵌套的 SELECT 而不是 JOIN 是否会影响性能? @neezer - 我认为你会受到轻微的性能损失,是的,但如果你的表被正确索引,它通常并不重要。这绝对是一种折衷的情况 - 检索字段并在每个建筑物中保留一条记录,但会牺牲一些额外的表查找。

以上是关于SQL 子选择作为字段?的主要内容,如果未能解决你的问题,请参考以下文章

带有子查询排除的 SQL 选择字段

MySql 查询出对应子表的某个字段,并且关联起来

SQL在文本字段中选择包含子字符串的行

SQL Regex - 用另一个字段的子字符串替换

sql子查询(急100分)

criteriabuilder 字段运算 怎么做