У меня есть две таблицы, units
и power
. Взгляни на:
Таблица 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 | |
+----------+--------------+-------------+----------+---------+--+
Объяснение:
Исключить конкретный идентификатор, должен работать одинаково как для одной строки, так и для строки, которая представляет собой сумму нескольких строк в таблице. Как видите, в результирующем наборе исключалась строка с id 1. Идентификатор предоставлен приложением, я думаю, что лучше сделать это в MySQL, чем PHP, потому что MySQL может просто отбросить эту строку (я думаю), но с PHP это должно было бы сделать if() проверку для каждой итерации цикла, которая кажется менее эффективным.
Показывать строку суммированных строк перед отдельными строками каждый раз.
Показывать пользовательские блоки перед другими пользователями, каждый раз. Вы можете видеть, что когда строки с user_id из 10 (представьте, что этот пользователь является тем, кто видит страницу), сначала появляются в моем результирующем наборе.
Сначала покажите единицы с максимальной мощностью.
Сначала показывайте единицы с наивысшим количеством.
Показывать единицы с наивысшим идентификатором.
Последние (4.5.6) сортируются относительно приоритета результирующего набора, причем четвертый имеет наибольшую часть. У меня есть этот запрос:
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 =. Затем я ВЫБРАТЬ введенный идентификатор отдельно для моего приложения, а затем ВЫБЕРИТЕ список. Но поскольку у меня уже есть данные для введенного идентификатора (например, 1 в этом случае) мне не нужно иметь их, когда я ВЫБИРАЮ из units
и power
.
@Anonymous, чтобы ответить на ваш вопрос 1, ответ 1: все строки с одинаковым group_id (кроме 0, который является маркером not-a-group
) сгруппированы и объединены вместе, поэтому строки, которые являются идентификаторами 4
, 5
и 6
которые имеют одинаковые 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, вам нужно щелкнуть по бегу, чтобы получить результаты.
То, что я не понимаю, - это спецификация 2: "показать сгруппированные перед негруппированными". Это означает, что единицы id 4 должны отображаться сначала в списке, чего нет в вашем примере.