3

嗨,我知道如何对 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

这甚至可能吗?

4

7 回答 7

4

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

原因:

  • Name字段是该数据行的属性
  • 如果你离开Name了,你怎么知道Location哪个名字是什么?
  • 您隐含地依赖数据的顺序,这在 SQL 中是一种非常糟糕的做法(因为返回的数据没有固有的顺序)
  • 任何解决方案都需要涉及游标或循环,这不是 SQL 优化的对象 - 它喜欢在 SETS 中工作,而不是在单个行上工作
于 2012-05-09T19:44:01.443 回答
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 正确指出的那样,我不必要地使用了外部选择、独特和原始的名称。我的错误是,当我使用 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

谢谢吉尔卡

于 2012-05-10T08:03:24.447 回答
2

如果您使用直接的 SQL*Plus 来制作报告(别笑,您可以用它做一些非常酷的事情),您可以使用BREAK 命令执行此操作:

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>
于 2012-05-09T20:02:18.960 回答
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 子句不负责分组作业,至少不直接负责。在第一个近似值中,同一个表的外连接(下面的左连接)可用于确定特定值第一次出现在哪一行。这就是我们所追求的。这假设有一些唯一id值可以任意排序所有记录。(ORDER BY 子句不这样做;它对输出进行排序,而不是对整个计算的输入进行排序,但仍然需要确保输出正确呈现,因为剩余的 SQL 并不暗示任何特定的处理顺序.)

如您所见,SQL 中仍有一个 GROUP BY 子句,但可能有意想不到的用途。它的工作是“撤消” LEFT JOIN 的副作用,即复制具有许多“先前”(=成功连接)记录的所有主记录。

这对于 GROUP BY 来说是很正常的。GROUP BY 子句的典型作用是减少记录数;并且无法查询或测试未在 GROUP BY 子句中列出的列,除非通过 COUNT、MIN、MAX 或 SUM 等聚合函数。这是因为由于 GROUP BY,这些列真正代表“值组”,而不仅仅是特定值。

于 2012-05-09T20:06:56.000 回答
1

如果您使用的是 SQL*Plus,请使用 BREAK 函数。在这种情况下,在 NAME 上中断。

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

于 2012-05-09T20:56:10.353 回答
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/

于 2016-05-16T05:09:11.020 回答
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 子句,请参考示例数据库。下表显示“订单”表中的字段: 1. |EMPORD_ID|employee1ID|customerID|shippers_ID|

下表显示了“托运人”表中的字段: 1. | 托运人_ID| 托运人_姓名 |

下表显示了“table_emp1”表中的字段: 1. | 员工1ID| first1_nm | 最后1_nm |

示例:查找每个发货人发送的订单数量。1. SELECT shipper.shippers_Name, COUNT (orders.EMPORD_ID) AS No_of_orders FROM orders LEFT JOIN shipper ON orders.shippers_ID = shipper.shippers_ID GROUP BY shippers_Name; 1. | 托运人_姓名 | No_of_orders | 示例:在多个列上使用 GROUP BY 语句。1. SELECT shipper.shippers_Name, table_emp1.last1_nm, COUNT (orders.EMPORD_ID) AS No_of_orders FROM ((orders INNER JOIN shipper 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. | 托运人_姓名 | last1_nm |No_of_orders |

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

于 2016-05-17T06:33:43.403 回答