SQL 查询表映射多对一

时间:2021-03-24 06:28:42

标签: sql sql-server

我有两张桌子。

Table 1 (P_Data)                                      Table 2 (Address)
| Data_Id | First_Name  | Last_Name |                 | ID | Data_Id  | Address_Type | address_data|
|---------|-------------|-----------|                 |----|----------|--------------|-------------|
| 1       | John        | Page      |                 | 1  | 1        | Residential  | address1    | 
| 2       | Bob         | Builder   |                 | 2  | 1        | Bill_To      | address2    |
                                                      | 3  | 2        | Residential  | address3    | 
                                                      | 4  | 2        | Bill_To      | address4    |

我想要一个只有 2 个字段的输出,但它必须包含属于 P_Data 表的每个 id 的所有地址(1 个或多个或无)。

也许喜欢

| Data_Id | First_Name  | Last_Name |  Address_Type | address_Data |                                                
|---------|-------------|-----------|---------------|--------------|
| 1       | John        | Page      | Residential   | address1     |
|         |             |           | Bill_To       | address2     |              
| 2       | Bob         | Builder   | Residential   | address3     |
|         |             |           | Bill_To       | address4     |               

有可能吗?或者不会重复 Data_Id 字段但也会提供所有地址字段的东西。

注意:对于一个 Data_Id,地址字段可以是无到 10。寻找通用查询。

编辑: 我试过了

SELECT pd.Data_Id, pd.First_Name, pd.Last_Name, a.Address_Type, a.address_data 
from P_Data as pd 
JOIN Address as a ON pd.Data_Id = a.Data_Id

得到这个作为输出

| Data_Id | First_Name  | Last_Name |  Address_Type | address_Data |                                                
|---------|-------------|-----------|---------------|--------------|
| 1       | John        | Page      | Residential   | address1     |
| 1       | John        | Page      | Bill_To       | address2     |              
| 2       | Bob         | Builder   | Residential   | address3     |
| 2       | Bob         | Builder   | Bill_To       | address4     |

2 个答案:

答案 0 :(得分:0)

在 SQL Server 2012 及更高版本中,您可以使用 lag

SELECT nullif(pd.Data_Id, lag(pd.Data_Id, 1, null) over (order by pd.Data_Id)) as Data_Id,
  nullif(pd.First_Name, lag(pd.First_Name, 1, null) over (order by pd.Data_Id)) as First_Name,
  nullif(pd.Last_Name, lag(pd.Last_Name, 1, null) over (order by pd.Data_Id)) as Last_Name,
  a.Address_Type, a.address_data 
from P_Data as pd 
JOIN Address as a ON pd.Data_Id = a.Data_Id
ORDER BY pd.Data_Id

答案 1 :(得分:0)

您可以使用 JOIN,将列设置为 NULL 并仔细对结果进行排序:

select (case when row_number() over (partition by t1.Data_Id order by t2.id) = 1
             then t1.data_id
        end) as data_id,
       (case when row_number() over (partition by t1.Data_Id order by t2.id) = 1
             then t1.First_Name
        end) as First_Name,
       (case when row_number() over (partition by t1.Data_Id order by t2.id) = 1
             then t1.Last_Name
        end) as Last_Name,
       t2.Address_Type, t2.address_Data
from table1 t1 left join
     table2 t2
     on t2.Data_Id = t1.Data_Id
order by t1.Data_Id, t2.id;

请注意,这种类型的转换通常最好在应用层完成。

相关问题