繁体   English   中英

SELECT,如何将某些行合并为一个,首先显示具有特定列值的行,并排除行

[英]SELECT, how to combine some rows as one, show rows with specific column value first and exclude a row

我有两个表, unitspower 看一眼:

power表:

+----+-------+
| id | power |
+----+-------+
|  1 |     2 |
|  2 |     4 |
|  3 |     6 |
|  4 |     8 |
+----+-------+

units表:

 +----+---------+----------+--------+----------+---+---+
    | id | user_id | power_id | amount | group_id | x | y |
    +----+---------+----------+--------+----------+---+---+
    |  1 |      10 |        3 |   1000 |        0 | 1 | 1 |
    |  2 |      10 |        3 |   1000 |        0 | 1 | 1 |
    |  3 |      10 |        3 |   1000 |        0 | 1 | 1 |
    |  4 |      11 |        2 |    100 |        4 | 1 | 1 |
    |  5 |      11 |        2 |    100 |        4 | 1 | 1 |
    |  6 |      11 |        1 |    100 |        4 | 1 | 1 |
    |  7 |      12 |        4 |   1000 |        0 | 1 | 1 |
    +----+---------+----------+--------+----------+---+---+

我想得到如下结果:

+----------+--------------+-------------+----------+---------+--+
| units.id | total_amount | total_power | group_id | user_id |  |
+----------+--------------+-------------+----------+---------+--+
|        3 |         1000 |        6000 |        0 |      10 |  |
|        2 |         1000 |        6000 |        0 |      10 |  |
|        4 |          300 |        1000 |        4 |      11 |  |
|        7 |         1000 |        8000 |        0 |      12 |  |
+----------+--------------+-------------+----------+---------+--+

说明:

  1. 排除特定的ID,对于单行和表中多行之和的行应相同。 如您所见,在结果集中,排除了ID为1的行。 id由应用程序提供,我认为在MySQL中比在PHP中更好,因为MySQL可以丢弃此行(我认为),但是对于PHP,它将必须执行if()检查每个循环迭代,这似乎效率较低。

  2. 每次都在单行之前显示汇总行。

  3. 每次都在其他用户之前显示用户单位。 您可以看到,当user_id10的行(假设该用户是看到页面的用户)出现在我的结果集中。

  4. 首先显示功率最高的设备。

  5. 首先显示金额最高的单位。

  6. 首先显示具有最高ID的单位。

根据结果​​集的优先级对last(4.5.6)进行排序,其中第4个具有最多的优先级。 我有这个查询:

SELECT   units.id,
         units.amount*power.power AS total_power,
         Sum(units.amount)        AS total_amount
FROM     units
JOIN     power
ON       units.power_id = power.id
WHERE    x = ?
AND      y = 1
GROUP BY group_id
ORDER BY group_id desc, total_power desc, total_amount desc, units.id desc limit ?,?

但是它组合了group_id为0的所有单位,但是我希望group_id=0单位成为结果集中的单独行。 怎么做? 谢谢!

编辑 :要回答@Linoff有关如何确定要排除的ID的问题,我在示例中排除了1 ,因为用户始终可以通过使用unit_id访问它来查看结果集,在我的示例中碰巧又是1 我希望现在已经清楚了。 编辑 :用户可以在页面“ index.php?page = unit / view&id =上访问此单元列表。然后我为我的应用程序分别选择输入的ID,然后选择列表。但是由于我已经有数据对于输入的ID(例如,本例中为1),当我从unitspower选择时,不需要它们。

@Anonymous,回答您的问题1,答案1是:用相同GROUP_ID所有行(除了0这是一个not-a-group标志物)被分组并组合在一起,所以行其是ID 456具有相同group_id被合并。 我的问题是,我不知道如何排除独立行的分组(无分组标记)以及如何对结果进行排序,以便将具有指定user_id的行排在首位并分组(排成4、5、6的行) -to-4)也将首先排序,但如果有意义,则以user_id = 10-first,user_id = ??-second的层次结构排序。

我想这就是你想要的:

CREATE TABLE Power  (id int,  power int);
CREATE TABLE demo (id integer primary key, name varchar(20), hint text);
CREATE TABLE units (id, user_id, power_id, amount, group_id, x, y);

SELECT   1 as spec2_HIDETHIS,  /* Spec 2 show the groupedrows first */
         units.id    as units_ID,
         units.amount*power.power AS total_power,
         units.amount        AS total_amount,
         units.group_id      as group_id
FROM     units
JOIN     power
ON       units.power_id = power.id
WHERE    units.group_id=0  /*  */
AND      units.id != 1  /* Spec no 1 : exclud specific id */
union 
SELECT   0 as spec2_HIDETHIS,  /* Spec 2 show the groupedrows first */
         min(units.id) as units_ID ,
         units.amount*power.power AS total_power,
         Sum(units.amount)        AS total_amount,
         units.group_id           as group_id
FROM     units
JOIN     power
ON       units.power_id = power.id
where    units.group_id > 0
AND      units.id != 1  /* Spec no 1 : exclud specific id */
GROUP BY group_id
ORDER BY spec2_HIDETHIS, group_id desc, total_power desc, total_amount desc, units_ID desc  

Fiddle Link ,您需要单击run以获得结果。

我不明白的是规范2:“在未分组之前先显示分组。”这意味着单元ID 4应该首先出现在列表中,而不是在您的示例中。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM