简体   繁体   English

在SQL中联接表,其中新列名基于另一列的联接表值

[英]Joining tables in SQL where new column name is based on joined table value from another column

I have 2 tables and I'm trying to join contents of the second table, into the first. 我有2个表,我正在尝试将第二个表的内容加入第一个表。 In essence i want to end up with a list of items that contains all fields from the first table, and all relevant rows in the second table, names after column content in the second table. 从本质上讲,我想以包含第一张表中的所有字段以及第二张表中的所有相关行,第二张表中列内容之后的名称的项目列表结尾。

Table A 表A

+----+--------+---------------------+--------+
| ID | Title  |        Date         | Etc... |
+----+--------+---------------------+--------+
|  1 | QWERTY | 0000-00-00:00:00:00 |    ... |
|  2 | TEST   | 0000-00-00:00:00:00 |    ... |
|  3 | ASDF   | 0000-00-00:00:00:00 |    ... |
|  4 | IOP    | 0000-00-00:00:00:00 |    ... |
+----+--------+---------------------+--------+

Table B 表B

+----+------------+------+------------+
| ID | Table_A_ID | Key  |   Value    |
+----+------------+------+------------+
|  1 |          1 | Name | John       |
|  2 |          2 | Name | Brad       |
|  3 |          1 | DOB  | 2000-01-16 |
+----+------------+------+------------+

So I'd like to be able to Select * from Table A and somehow end up with the following 因此,我希望能够从表A中选择*并以某种方式结束以下操作

+----+--------+---------------------+--------+------+------------+
| ID | Title  |        Date         | Etc... | Name |    DOB     |
+----+--------+---------------------+--------+------+------------+
|  1 | QWERTY | 0000-00-00:00:00:00 |    ... | John | 2000-01-16 |
|  2 | TEST   | 0000-00-00:00:00:00 |    ... | Brad |            |
|  3 | ASDF   | 0000-00-00:00:00:00 |    ... |      |            |
|  4 | IOP    | 0000-00-00:00:00:00 |    ... |      |            |
+----+--------+---------------------+--------+------+------------+

The key thing is that i don't know what the keys are going to be 关键是我不知道关键是什么

Unfortunately I have no idea what this is called to google it, I've been looking through the inner, left, right joins and these don't seem to do what I'm trying to do. 不幸的是,我不知道用什么来谷歌搜索它,我一直在通过内,左,右连接进行查找,而这些似乎并没有执行我想做的事情。

This can be achieved with two JOINs on TableB, like : 这可以通过在TableB上使用两个JOIN来实现,例如:

SELECT
    ta.id,
    ta.date,
    ta.etc,
    tb.value Name,
    td.value DOB
FROM
    tableA ta
    INNER JOIN tableB tb ON tb.table_a_id = tb.id AND tb.key = 'Name'
    INNER JOIN tableB td ON td.table_a_id = ta.id AND td.key = 'DOB'

With this query, only records that do have a Name and a DOB in TableB will be displayed. 通过此查询,将仅显示在TableB中确实具有名称和DOB的记录。 If you want to avoid filtering out these "incomplete" records, you can use LEFT JOIN instead of INNER JOIN. 如果要避免过滤掉这些“不完整”的记录,可以使用LEFT JOIN而不是INNER JOIN。

Select a.*, 
(select TOP 1  b.DOB from b where b.table_a_id = a.id and b.key = 'dob'), 
(select TOP 1 b.ame from b where b.table_a_id = a.id and b.key = 'name') 
from a

You have to use sub-selects to achieve that results 您必须使用子选择来实现该结果

You're looking to pivot the keyed values. 您正在寻找枢纽键值。 You can do that manually like this: 您可以像这样手动进行操作:

select a.*
     , max(case b.key when 'Name' then b.value end) Name
     , max(case b.key when 'DOB' then b.value end) DOB
  from TableA a
  left join TableB b
    on a.id = b.table_a_id
  group by a.id
      , a.title
      , a.date
      , a.etc

The above query will work if you only have one of each attribute for a given record in TableA, otherwise it will give you the largest value. 如果您只有TableA中给定记录的每个属性之一,则上述查询将起作用,否则它将为您提供最大的价值。 If you want multiple values, you can generate a sequence for each attribute as shown in the subselect named B below: 如果需要多个值,则可以为每个属性生成一个序列,如下面名为B的子选择所示:

select a.ID
     , b.Seq
     , a.Title
     , a.Date
     , a.Etc
     , max(case b.key when 'Name' then b.value end) Name
     , max(case b.key when 'DOB' then b.value end) DOB
  from TableA a 
  left join (select @Seq:=case
                       when @aid=b.Table_A_ID and @key=b.key
                       then @Seq + 1
                       else 1
                     end Seq
                   , @aid:=b.Table_A_ID Table_A_ID
                   , @key:=b.key `Key`
                   , b.value
                from tableB b
               order by table_a_id, b.key) b
     on a.id = b.table_a_id
  group by a.id, a.title, a.date, a.etc, b.Seq;

This is different than @GMB's response in that it will return each attribute only once with nulls in rows where there are fewer values per attribute whereas @GMB's solution will return the CROSS product of all attributes for a given row. 这与@GMB的响应不同之处在于,它只会返回每个属性一次,并且每个属性中的值较少的行将返回空值,而@GMB的解决方案将返回给定行所有属性的CROSS乘积。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM