带分组的sql语句

时间:2009-09-14 08:44:02

标签: sql group-by

经过非常长的SQL查询后,得到的结果是这种形式:

 col1 | col2 | col3 | col4
------+------+------+-----
1234  | 1    | aaaa | bbbb
2378  | 0    | aaaa | bbbb
9753  | 1    | cccc | uuuu
1234  | 0    | iiii | yyyy
2378  | 1    | iiii | yyyy
9753  | 1    | tttt | mmmm

但我不需要这样。我必须在这个结果上做另一个sql语句,我必须使用 group by 第三和第四列。 换句话说,一行中有两行,如下所示:

col1 | col2 | col3 | col4 | col5 | col6
-----+------+------+------+------+-----
1234 | 1    | 2378 | 0    | aaaa | bbbb
1234 | 1    | 2378 | 0    | aaaa | bbbb
9753 | 1    | null | null | cccc | uuuu
1234 | 0    | 2378 | 1    | iiii | yyyy
9753 | 1    | null | null | tttt | mmmm

3 个答案:

答案 0 :(得分:2)

您可以通过创建两个额外的表(临时与否,取决于您的要求和SQL引擎)来解决该问题,哪个结构将从查询中映射列。

例如:

CREATE TABLE TableA (
  Col1 int,
  Col2 bit,
  Col3 varchar(4),
  Col4 varchar(4)
)

CREATE TABLE TableB (
  Col1 int,
  Col2 bit,
  Col3 varchar(4),
  Col4 varchar(4)
)

请注意,这只是基于您提供的输出数据的示例结构。

在创建这两个表之后,您必须将查询中的数据插入到每个表中。

添加了: 您不必执行两次相同的查询。执行一次,将数据放入TableA,然后在TableA上生成SELECT并将数据放入TableB。这将为您节省大量时间。

最后一步是在TableA和TableB上对其列Col3和Col4上的JOIN执行查询。像这样:

SELECT A.Col1, A.Col2, B.Col1, B.Col2, COALESCE(A.Col3, B.Col3), COALESCE(A.Col4, B.Col4)  
FROM TableA A INNER JOIN TableB B ON A.Col3 = B.Col3 AND A.Col4 = B.Col4

希望这会有所帮助。

另请注意,此解决方案有一个主要缺点:

如果在oryginal查询中更改列数或其数据类型,则还必须更新表定义。 可能的解决方案是使用动态sql,但通常不建议。

编辑后(您在输出数据中提供了额外的NULLS):

如果要保留NULL值,则应使用不同的连接,例如:LEFT OUTER JOIN

另一种可能的解决方案是:

  1. 只需用长查询替换(SELECT * FROM dbo.Test)。 但是这会导致查询运行两次。

    SELECT A. *,B. * FROM(SELECT * FROM dbo.Test)LEFT OUTER JOIN(SELECT * FROM dbo.Test)B ON A.Col3 = B.Col3 AND A.Col4 = B.Col4 AND A.Col1<> B.Col1和A.Col2<> B.Col2

  2. 如果使用SQL 2005,可以尝试使用CROSS APPLY运算符。

  3. 可能还有其他解决方案,但您必须更加描述您使用的SQL引擎以及您对数据库的权限。

答案 1 :(得分:1)

嗯,

我把结果扔到临时表中。 然后做

select 
a.col1, 
a.col2, 
b.col1,
b.col2,
coalesce(a.col3, b.col3) as col5, 
coalesce(a.col4,b.col4) as col6 
from #tmp a 
outer join #tmp b 
on a.col3 = b.col3 and a.col4 = b.col4 
where a.col2 = 0 and b.col2 = 1

这是假设col2是你对的哪一部分的指示。

答案 2 :(得分:0)

我找到了正确的解决方案,基于 @Wodzu 的第一个解决方案。

首先,创建一个包含结果的临时视图。

用tmp作为 ( - 我很长的sql语句...... )

其次,选择因为有两个,这样查询只被调用一次。

从tmp中选择一个。**,b。**,条件为内连接tmp b。

感谢Wodzu