mysql - 非常高级的 sql 查询的问题

标签 mysql sql dynamicquery

我需要在 SQL 中进行高级选择,但我陷入困境。

我有下表:

id | user_id | position | value
1  |   1     |    1     |   1
1  |   1     |    2     |   1
1  |   1     |    3     |   3
1  |   2     |    1     |   2
1  |   2     |    2     |   2
1  |   2     |    3     |   2
1  |   3     |    1     |   3
1  |   3     |    2     |   2
1  |   3     |    3     |   1

我需要一个查询,为我提供一个按如下顺序排序的结果集:

  1. 每个用户的总金额(用户 1: 5、用户 2: 6、用户 3: 6)
  2. 每个用户的位置 3 的值(用户 1: 3、用户 2: 2、用户 3: 1)
  3. 每个用户的 pos 3 的 val + pos 2 的 val(用户 1: 4、用户 2: 4、用户 3: 4)
  4. 每个用户的 pos 3 的 val + pos 2 的 val + pos 1 的 val(用户 1: 5、用户 2: 6、用户 3: 6)

这只是一个示例,表实际上可以包含更多位置,因此我需要一个不在三个位置上硬编码的查询。

注意:每个 user_id 的位置数始终相同。在本示例中为三个,但我也可以截断表并使用五个位置为每个用户添加数据。

一个丑陋的解决方案是假设位置永远不会超过十个,创建 pos1、pos2 等作为列,然后将它们相应地添加到查询中。如果您只使用三个位置,您会得到很多 NULL 值,并且您还会陷入最多十个位置的困境。

我考虑过使用临时表,但也没有找到突破口。

你会怎么做?

最佳答案

I need a query that is not hard coded on three positions.

那么您就无法在中输出小计。 SQL 要求在准备查询时固定列;您无法编写动态附加更多列的查询,因为它会发现数据中有多少个不同的值。

但是,您可以输出动态数量的

SELECT t1.user_id, CONCAT(t1.position, '-', MAX(t2.position)) AS position_range, 
  SUM(t2.value) AS subtotal
FROM MyTable t1
INNER JOIN MyTable t2
  ON t1.user_id = t2.user_id AND t1.position <= t2.position
GROUP BY t1.user_id, t1.position;

输出为:

+---------+----------------+----------+
| user_id | position_range | subtotal |
+---------+----------------+----------+
|       1 | 1-3            |        5 |
|       1 | 2-3            |        4 |
|       1 | 3-3            |        3 |
|       2 | 1-3            |        6 |
|       2 | 2-3            |        4 |
|       2 | 3-3            |        2 |
|       3 | 1-3            |        6 |
|       3 | 2-3            |        3 |
|       3 | 3-3            |        1 |
+---------+----------------+----------+

在获取整个结果集后,您必须编写应用程序代码才能将其转换为列。

抱歉,在任何品牌的 RDBMS 中都无法编写完全动态的数据透视查询。您有两个选择:

  1. 编写代码以根据数据生成 SQL,如 @TimLehner 的更新答案所示

  2. 编写代码来后处理通用查询,如我上面所示的查询。

关于mysql - 非常高级的 sql 查询的问题,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/15929926/

相关文章:

sql - 按键值表中的多行过滤结果

mysql - 仅在记录不存在时插入行

sql - SSIS动态查询

php - 在 PHP 中打印出以逗号分隔的关联数组列的最简单方法(来自 MYSQL)

mysql - Google Cloud SQL 中的 optimizer_search_depth

mysql - 如何使用MySQL优化表是否包含10000个条目的查询?

mysql - 使用wamp的mysql地址

mysql - 如何从MySQL数据库中选择最新日期

arrays - Rails 3 检索所有曾孙记录作为 ActiveRecord 集合

java - 使用 JDBC Statement 或PreparedStatement 执行一组查询