Java 如何从联接表中为每个主键项仅选择一条记录?

Java 如何从联接表中为每个主键项仅选择一条记录?,java,oracle,Java,Oracle,我有两张桌子,分别是Hotels和Description。描述表包含每个酒店的描述 在hotels表中,id和city_id一起构成主键(id本身不是主键) 在描述表中,每家酒店最多可以有8种描述类型(概述、位置、房间、外部、请柬、包含在内、大堂) 我想使用Hotel表和Description表更新主表。对于Hotel表中的每条记录,我应该在主表中插入一行。当我执行left outer join时,Hotel表中的每个记录都会生成多个记录,因为一个酒店有0个或多个描述类型 我只想从描述表中为

我有两张桌子,分别是Hotels和Description。描述表包含每个酒店的描述

  • 在hotels表中,id和city_id一起构成主键(id本身不是主键)
  • 在描述表中,每家酒店最多可以有8种描述类型(概述、位置、房间、外部、请柬、包含在内、大堂)
我想使用Hotel表和Description表更新主表。对于Hotel表中的每条记录,我应该在主表中插入一行。当我执行left outer join时,Hotel表中的每个记录都会生成多个记录,因为一个酒店有0个或多个描述类型

我只想从描述表中为每个酒店选择一个描述,它并不总是第一个描述。(如果是的话,我可以用)。相反,我有描述类型的优先级顺序。首先,我需要检查是否有“一般”描述。如果有,那么应该是主表的描述,并且应该跳过酒店的其余描述。如果“常规”描述类型不可用,那么我想检查“位置”描述类型是否可用,依此类推

我试图为此编写Oracle SQL查询,但它并不能完全满足我的要求

下面是我用来连接两个表(每个酒店有多行)的查询。在遵守上述指导原则的情况下,如何为每家酒店筛选出一行

代码:


我试图使用解码功能,但似乎它不做的工作

您可以在sql中使用CASE表达式为描述类型给出一个顺序,按此顺序排序,然后使用您提到的链接获取组中的第一个。像下面这样

SELECT HOTEL_DETAILS.*,
    CASE Description.Desc_type
      WHEN 'general' THEN 0
      WHEN 'location' THEN 1
      WHEN 'rooms' THEN 2
      WHEN 'lobby' THEN 3
      ELSE 99 
    END desc_order,
    Description.description
    FROM
     (SELECT Hotel.id,
             Hotel.city_id,
             Hotel.hotel_name,         
             City.country_code
           FROM Hotel
           LEFT OUTER JOIN City
           ON Hotel.city_id=City.city_id
     ) HOTEL_DETAILS
   LEFT OUTER JOIN Description
   ON HOTEL_DETAILS.id    =Description.id
   AND HOTEL_DETAILS.city_id    = Description.city_id
   ORDER BY HOTEL_DETAILS.id, HOTEL_DETAILS.city_id, desc_order

谢谢你的回答,德拉比。这对我帮助很大
SELECT HOTEL_DETAILS.*,
    CASE Description.Desc_type
      WHEN 'general' THEN 0
      WHEN 'location' THEN 1
      WHEN 'rooms' THEN 2
      WHEN 'lobby' THEN 3
      ELSE 99 
    END desc_order,
    Description.description
    FROM
     (SELECT Hotel.id,
             Hotel.city_id,
             Hotel.hotel_name,         
             City.country_code
           FROM Hotel
           LEFT OUTER JOIN City
           ON Hotel.city_id=City.city_id
     ) HOTEL_DETAILS
   LEFT OUTER JOIN Description
   ON HOTEL_DETAILS.id    =Description.id
   AND HOTEL_DETAILS.city_id    = Description.city_id
   ORDER BY HOTEL_DETAILS.id, HOTEL_DETAILS.city_id, desc_order
    SELECT dtl.id,
           dtl.city_id,
           dtl.hotel_name,
           dtl.country_code,
           min(dsc.desc_type)   KEEP (DENSE_RANK FIRST ORDER BY CASE dsc.desc_type WHEN 'general' THEN 1 WHEN 'location' THEN 2 WHEN 'rooms' THEN 3 WHEN 'lobby' THEN 4 ELSE 5 END) desc_type,
           min(dsc.description) KEEP (DENSE_RANK FIRST ORDER BY CASE dsc.desc_type WHEN 'general' THEN 1 WHEN 'location' THEN 2 WHEN 'rooms' THEN 3 WHEN 'lobby' THEN 4 ELSE 5 END) description
      FROM (SELECT htl.id,
                   htl.city_id,
                   htl.hotel_name,         
                   cty.country_code
              FROM hotel htl
                   LEFT OUTER JOIN city cty
                     ON (htl.city_id = cty.city_id)) dtl
           LEFT OUTER JOIN dsc
             ON (   dtl.id = dsc.id
                AND dtl.city_id = dsc.city_id)
    GROUP BY dtl.id,
             dtl.city_id,
             dtl.hotel_name,
             dtl.country_code,