【问题标题】:Left join in sql table?在sql表中左连接?
【发布时间】:2020-03-04 12:50:47
【问题描述】:

我有以下 SQL Server 表:

+-------+----------+----------+----------+
| group | subgroup | position |  value   |
+-------+----------+----------+----------+
| D924  | A        | 50       | 9144142  |
| D924  | A        | 52       | 9268118  |
| D924  | A        | 60       | 9144588  |
| D924  | A        | 70       | 10116006 |
| D924  | A        | 110      | 9074177  |
| D924  | A        | 171      | 7367052  |
| D924  | A        | 180      | 10118595 |
| D924  | A        | 190      | 9074522  |
| D924  | B        | 150      | 12423396 |
| D955  | ...      | ...      | ...      |
+-------+----------+----------+----------+

我需要为每个subgroup 列出所有position 在同一个内 group

像这样:

+-------+----------+----------+----------+
| group | subgroup | position |  value   |
+-------+----------+----------+----------+
| D924  | A        | 50       | 9144142  |
| D924  | A        | 52       | 9268118  |
| D924  | A        | 60       | 9144588  |
| D924  | A        | 70       | 10116006 |
| D924  | A        | 110      | 9074177  |
| D924  | A        | 171      | 7367052  |
| D924  | A        | 180      | 10118595 |
| D924  | A        | 190      | 9074522  |
| D924  | A        | 150      |          |
| D924  | B        | 50       |          |
| D924  | B        | 52       |          |
| D924  | B        | 60       |          |
| D924  | B        | 70       |          |
| D924  | B        | 110      |          |
| D924  | B        | 171      |          |
| D924  | B        | 180      |          |
| D924  | B        | 190      |          |
| D924  | B        | 150      | 12423396 |
| D955  | ...      | ...      | ...      |
+-------+----------+----------+----------+

我想在单个 SQL 查询中实现结果表。能给点建议吗?

【问题讨论】:

标签: sql sql-server database tsql


【解决方案1】:

这只是position[Group]subgroup 值的DISTINCT 列表以及LEFT JOIN 返回表格。

执行 2 个DISTINCT 查询会很昂贵,因此如果您有一个包含您的组和职位的表格,我建议您使用这些,而不是 CTE:

WITH Groups AS
    (SELECT DISTINCT
            [group],
            subgroup
     FROM dbo.YourTable),
Positions AS
    (SELECT DISTINCT
            position
     FROM dbo.YourTable)
SELECT G.[Group],
       G.subgroup,
       P.Position,
       YT.[value]
FROM Groups G
     CROSS JOIN Positions P
     LEFT JOIN dbo.YourTable YT ON G.[Group] = YT.[Group]
                               AND G.subgroup = YT.subgroup
                               AND P.Position = YT.Position;

【讨论】:

  • 这非常接近结果。唯一的问题是您的查询给了我其他Groups 的位置,我只想要位置 50,52,60,70,110,150,171,180 和 190。如果组 D955 有位置 390,我不希望它在D924 行
  • 似乎您在@JohanB 此处没有提供足够的样本数据。这是一个关于组和子组的DISTINCT,所以不能完全确定这里的问题。
【解决方案2】:

您似乎只想要每个组中第一个“位置”的值。这表明row_number()

select group, subgroup, position,
       (case when row_number() over (partition by group, position order by subgroup) = 1
             then value
        end) as value
from t;

Here 是一个 dbfiddle。

【讨论】:

  • 这在源表中给了我完全相同的结果
  • @JohanB 。 . .我添加了一个 dbfiddle 来说明它的工作原理。
【解决方案3】:

首先选择不同的子组和位置,然后加入它们并外部加入您的表。

with sub as (select distinct group, subgroup from mytable)
   , pos as (select distinct group, position from mytable)
select
  sub.group. sub.subgroup, pos.position, t.value
from sub
join pos on pos.group = sub.group
left join mytable t on t.group = sub.group
                   and t.subgroup = sub.subgroup
                   and t.position = pos.position
order by t.group, t.subgroup, t.position;

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-10-02
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多