SQL Server,将列中的所有值与另一个值的一些值连接起来

Posted

技术标签:

【中文标题】SQL Server,将列中的所有值与另一个值的一些值连接起来【英文标题】:SQL Server, joining all values in column with some values of another 【发布时间】:2018-08-16 18:42:43 【问题描述】:

我很不擅长解释,所以我会尽量让我的例子来做大部分的谈话。假设我有一张这样的桌子:

          dbo.ExampleTable
===================================


  ID     Year     Data1     Data2
====== ======== ========= =========
  12     2016      FOO       BAR
  13     2016      FOO       MAN
  14     2016      SAW       BAR

  20     2017      FOO       BAR
  21     2017      FOO       MAN
  27     2017      SAW       BAR
  29     2017      CHU       CAR

  44     9999      FOO       BAR
  48     9999      FOO       MAN
  51     9999      SAW       BAR
  52     9999      CHU       CAR

一些注意事项:

ID 是唯一的 (年份,Data1,Data2)是唯一的 “年份”列中的唯一值将是 2016、2017 或 9999

我想根据该数据创建一个如下所示的表:

  ID_9999     ID_2016     ID_2017  
=========== =========== ===========
     44          12          20
     48          13          21
     51          14          27
     52         NULL         29

因此,基本上,对于 Year=9999 的 Data1 和 Data2 的每个唯一配对,我想创建一个行,其中包含 Year=9999 的配对的 ID,以及 Year=2016 和的配对的 ID年=2017。此外,如果 2016 或 2017 不包含该数据配对,我希望它们的值为 NULL。

这是我目前得到的查询:

SELECT      tbl9999.ID       ID_9999,
            tbl2016.ID       ID_2016,
            tbl2017.ID       ID_2017

FROM        dbo.ExampleTable tbl9999

LEFT JOIN   dbo.ExampleTable tbl2016
ON          tbl9999.Data1 = tbl2016.Data1
AND         tbl9999.Data2 = tbl2016.Data2

LEFT JOIN   dbo.ExampleTable tbl2017
ON          tbl9999.Data1 = tbl2017.Data1
AND         tbl9999.Data2 = tbl2017.Data2

WHERE       tbl9999.Year=9999
AND         tbl2016.Year=2016
AND         tbl2017.Year=2017

这似乎工作得很好,但是它会生成一个像这样的表:

  ID_9999     ID_2016     ID_2017  
=========== =========== ===========
     44          12          20
     48          13          21
     51          14          27

*请注意,在上面的示例中,它缺少具有空值的行。有什么方法可以更改我的查询以包含该空值,以便在我的示例中包含它?

如果我遗漏任何信息或需要澄清任何内容,请告诉我。提前致谢!

编辑: 我能够自己找到答案!这是我用来达到我想要的结果的代码:

SELECT      [9999] [ID_9999],
            [2016] [ID_2016],
            [2017] [ID_2017]
FROM        dbo.ExampleTable
PIVOT       (MAX([ID]) FOR [Year] IN ([2016],[2017],[9999])) [x]
ORDER BY    ID_9999

【问题讨论】:

将 where 子句移动到连接...即LEFT JOIN dbo.ExampleTable tbl2016 on .... and tbl2016.Year=2016 【参考方案1】:

您可以通过多种方式做到这一点。条件聚合似乎很简单:

select max(case when year = 2016 then id end) as id_2016,
       max(case when year = 2017 then id end) as id_2017,
       max(case when year = 9999 then id end) as id_9999

from (select t.*, row_number() over (partition by year order by id) as seqnum
      from dbo.ExampleTable t
     ) t
group by seqnum
order by seqnum;

【讨论】:

这与我正在寻找的非常接近,但是当我与我的数据集进行比较时,结果有点偏离。它似乎生成了正确数量的结果,但是,ID 对我来说并没有正确匹配。它似乎将三年中每一年的最低 ID 分组到一行中,然后在下一行中每三年中的下一个最低值,依此类推。我应该提到我的数据集不是迭代的,因为它出现在我的示例中。虽然 ID 是唯一的,但它没有排序,年份和 ID 分散在我的数据集中。这会影响您的回答吗? @JonWarren 。 . . id 应该以数字顺序显示,与示例数据中的方式完全相同。只要id 是唯一的,这应该会产生相同的答案。

以上是关于SQL Server,将列中的所有值与另一个值的一些值连接起来的主要内容,如果未能解决你的问题,请参考以下文章

pyspark 将列值与另一列进行比较包含值范围

返回查询的所有行,其中一列中的字符串值与另一列中的字符串值匹配

ms sql server字符串与另一个具有多个值的字符串进行比较

SQL将列中的所有行设置为其他列的倍数

SQL Server 2008 R2 - 将列转换为行并将所有值放在一列中

在python中,我如何对一列中每个值与另一列中的值发生的次数(多少行)建立矩阵?