【问题标题】:sql statement with group by带有分组依据的sql语句
【发布时间】:2010-11-28 01:39:16
【问题描述】:

在很长的 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

【问题讨论】:

  • 不同行的不同架构?这会很棘手。
  • soryy,我改变了它。每一行都使用相同的架构。

标签: sql group-by


【解决方案1】:

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

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

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

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

select a.**, b.** from tmp a inner join tmp b on conditions.

感谢沃祖

【讨论】:

    【解决方案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
    

    希望这会有所帮助。

    另外请记住,此解决方案有一个主要缺点:

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

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

    如果你想保留NULL值,你应该使用不同的join,例如:LEFT OUTER JOIN

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

    1. 只需将 (SELECT * FROM dbo.Test) 替换为您的长查询。 但是,这将导致该查询将运行两次。

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

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

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

    【讨论】:

    • 这个答案非常正确,而且效果很好。但是,我的这个查询给出的结果应该运行至少 1 小时。目前必须将其插入表中,我想我必须运行它两次。这意味着大约 2 小时。但是,离这个答案不要太远......如果一个视图中有查询的结果,并且我将其与自身进行内部连接,我认为这个想法是相同的,我只需要运行一次。现在的问题是如何与自身进行内部连接???我想,我还需要做一些工作。
    • @Florjon 您不必运行两次。运行一次,将数据插入到 TableA 中,而不仅仅是在 TableA 上进行 SELECT 并从该选择中将数据插入到 TableB 中。
    • 好的,你说的对。问题是数据库是银行数据库,我什至无法想象创建表或视图。我现在要做的是:
      用 tmp 作为(我的选择 ...)
      内连接 tmp
      on ...

      有什么想法吗?
    • @Florjon:下次提问时请更具体一些。提供尽可能多的信息。有关 SQL 引擎的信息和您对数据库的权限非常重要。另请检查我制作的其他解决方案。
    【解决方案3】:

    嗯,

    我会将结果放入临时表中。 然后做

    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 是您拥有该货币对的哪一部分的指标。

    【讨论】:

      猜你喜欢
      • 2012-05-18
      • 1970-01-01
      • 2010-09-06
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2022-11-02
      • 2013-05-13
      • 1970-01-01
      相关资源
      最近更新 更多