如何按列分组

时间:2012-05-09 19:40:29

标签: sql oracle

您好我知道如何为sql使用group by子句。我不知道如何解释这个,所以我画了一些图表。这是我的原始数据:

Name          Location
----------------------
user1         1
user1         9
user1         3
user2         1
user2         10
user3         97

这是我需要的输出

Name          Location
----------------------
user1         1
              9
              3
user2         1
              10
user3         97

这甚至可能吗?

7 个答案:

答案 0 :(得分:5)

通常的方法是在表示层中处理它,而不是在数据库层中处理它。

原因:

  • Name字段是该数据行的属性
  • 如果您退出Name,您如何知道Location与哪个名称相关?
  • 您隐含地依赖于数据的顺序,这在SQL中是一种非常糟糕的做法(因为返回的数据没有固有的排序)
  • 任何解决方案都需要涉及游标或循环,这不是SQL优化的 - 它喜欢在SETS中工作而不是在单个行上工作

答案 1 :(得分:3)

希望这有帮助


SELECT A.FINAL_NAME, A.LOCATION
  FROM (SELECT DISTINCT DECODE((LAG(YT.NAME, 1) OVER(ORDER BY YT.NAME)),
                               YT.NAME,
                               NULL,
                               YT.NAME) AS FINAL_NAME,
                        YT.NAME,
                        YT.LOCATION
          FROM YOUR_TABLE_7 YT) A

正如Jirka正确指出的那样,我不必要地使用了外部select,distinct和raw名称。我的错误在于,当我使用DISTINCT时,我将结果排序为


1           1
2   user2   1
3   user3   97
4   user1   1
5           3
6           9
7          10

我想避免像这样输出。

因此我添加了原始ID和外部选择

但是,删除DISTINCT可以解决问题。 因此只有这么多就足够了


SELECT DECODE((LAG(YT.NAME, 1) OVER(ORDER BY YT.NAME)),
              YT.NAME,
              NULL,
              YT.NAME) AS FINAL_NAME,
       YT.LOCATION
  FROM SO_BUFFER_TABLE_7 YT

谢谢Jirka

答案 2 :(得分:2)

如果你使用直接的SQL * Plus来制作你的报告(不要笑,你可以用它做一些非常酷的东西),你可以用BREAK command来做到这一点:

SQL> break on name
SQL> WITH q AS (
SELECT 'user1' NAME, 1 LOCATION FROM dual
UNION ALL
SELECT 'user1', 9 FROM dual
UNION ALL
SELECT 'user1', 3 FROM dual
UNION ALL
SELECT 'user2', 1 FROM dual
UNION ALL
SELECT 'user2', 10 FROM dual
UNION ALL
SELECT 'user3', 97 FROM dual
)
SELECT NAME,LOCATION
  FROM q
 ORDER BY name;

NAME    LOCATION
----- ----------
user1          1
               9
               3
user2          1
              10
user3         97

6 rows selected.

SQL>

答案 3 :(得分:1)

我不得不同意其他评论者认为这种问题看起来不应该使用SQL来解决,但无论如何我们都要面对它。

SELECT
    CASE main.name WHERE preceding_id IS NULL THEN main.name ELSE null END,
    main.location
FROM mytable main LEFT JOIN mytable preceding
    ON main.name = preceding.name AND MIN(preceding.id) < main.id
GROUP BY main.id, main.name, main.location, preceding.name
ORDER BY main.id

GROUP BY子句不对分组作业负责,至少不直接负责。在第一个近似中,可以使用同一个表的外连接(下面的LEFT JOIN)来确定第一次出现特定值的行。这就是我们追求的目标。这假定存在一些唯一的id值,可以任意排序所有记录。 (ORDER BY子句不执行此操作;它对输出进行排序,而不是整个计算的输入,但仍然需要确保输出正确显示,因为剩余的SQL并不意味着任何特定的处理顺序。)

正如您所看到的,SQL中仍然存在GROUP BY子句,但可能出乎意料。它的工作是“撤消”LEFT JOIN的副作用,它是具有许多“前”(=成功加入)记录的所有主记录的重复。

GROUP BY非常正常。 GROUP BY子句的典型效果是减少记录数量;并且不可能查询或测试未在GROUP BY子句中列出的列,除非通过COUNT,MIN,MAX或SUM等聚合函数。这是因为这些列实际上代表了由GROUP BY引起的“值组”,而不仅仅是特定值。

答案 4 :(得分:1)

如果您使用的是SQL * Plus,请使用BREAK功能。在这种情况下,请打破NAME。

如果您使用其他报告工具,则可以将“名称”字段与之前的记录进行比较,并在相同时禁止打印。

答案 5 :(得分:1)

如果您使用GROUP BY,则输出行将根据GROUP BY列进行排序,就好像您对同一列有ORDER BY一样。 为了避免GROUP BY产生的排序开销,添加ORDER BY NULL:

SELECT a, COUNT(b) FROM test_table GROUP BY a ORDER BY NULL;

不推荐依赖MySQL 5.6中的隐式GROUP BY排序。要实现分组结果的特定排序顺序,最好使用显式ORDER BY子句。 GROUP BY排序是一个MySQL扩展,可能在将来的版本中发生变化;例如,使优化器能够以其认为最有效的方式对分组进行排序,并避免排序开销。

有关完整信息 - http://academy.comingweek.com/sql-groupby-clause/

答案 6 :(得分:0)

SQL GROUP BY语句 SQL GROUP BY子句与SELECT语句协作使用,以将相同的数据排列到组中。 句法: 1. SELECT column_nm,aggregate_function(column_nm)FROM table_nm WHERE column_nm operator value GROUP BY column_nm; 示例: 要理解GROUP BY子句,请参阅示例数据库。显示“order”表中字段的下表: 1. | EMPORD_ID | employee1ID | customerID | shippers_ID |

下表显示“发货人”表格中的字段: 1. | shippers_ID | shippers_Name |

下表显示了“table_emp1”表中的字段: 1. | employee1ID | first1_nm | last1_nm |

示例: 查找每个托运人发送的订单数量。 1.选择shipper.shippers_Name,COUNT(orders.EMPORD_ID)AS No_of_orders FROM订单LEFT JOIN发货人ON订单.shippers_ID = shipper.shippers_ID GROUP BY shippers_Name; 1. | shippers_Name | No_of_orders | 示例: 在多个列上使用GROUP BY语句。 1. SELECT shipper.shippers_Name,table_emp1.last1_nm,COUNT(orders.EMPORD_ID)AS No_of_orders FROM((订单INNER JOIN发货人ON orders.shippers_ID = shipper.shippers_ID)INNER JOIN table_emp1 ON orders.employee1ID = table_emp1.employee1ID) 2. GROUP BY shippers_Name,last1_nm;

  1. | shippers_Name | last1_nm | No_of_orders |
  2. 有关更多说明,请参阅我的链接 http://academy.comingweek.com/sql-groupby-clause/