В Mysql я хочу выбрать нижнюю часть 2 объекта из каждой категории
Category Value
1 1.3
1 4.8
1 3.7
1 1.6
2 9.5
2 9.9
2 9.2
2 10.3
3 4
3 8
3 16
Предоставление меня:
Category Value
1 1.3
1 1.6
2 9.5
2 9.2
3 4
3 8
Прежде чем я мигрировал от sqlite3, я должен был сначала выбрать самое низкое из каждой категории, затем, исключая что-либо, что соединило, к которому, я должен был снова выбрать самое низкое из каждой категории. Затем что-либо равняется этому новому самый низкий или меньше в выигранной категории. Это также выбрало бы больше чем 2 в случае связи, которая была раздражающей... Это также имело действительно длинное время выполнения.
Моя конечная цель должна считать количество раз, человек находится в одной из самых низких 2 из категории (существует также поле имени), и это - одна первая часть, не знают, как сделать.Спасибо
Вы можете попробовать следующее:
SELECT * FROM (
SELECT c.*,
(SELECT COUNT(*)
FROM user_category c2
WHERE c2.category = c.category
AND c2.value < c.value) cnt
FROM user_category c ) uc
WHERE cnt < 2
Это должно дать вам желаемый результат, но проверьте, в порядке ли производительность.
Профсоюз должен работать. Я не уверен в производительности по сравнению с решением Питера.
SELECT smallest.category, MIN(smallest.value)
FROM categories smallest
GROUP BY smallest.category
UNION
SELECT second_smallest.category, MIN(second_smallest.value)
FROM categories second_smallest
WHERE second_smallest.value > (SELECT MIN(smallest.value) FROM categories smallest WHERE second.category = second_smallest.category)
GROUP BY second_smallest.category
Вот решение, которое правильно обрабатывает дубликаты. Имя таблицы - 'zzz', а столбцы - int и float
select
smallest.category category, min(smallest.value) value
from
zzz smallest
group by smallest.category
union
select
second_smallest.category category, min(second_smallest.value) value
from
zzz second_smallest
where
concat(second_smallest.category,'x',second_smallest.value)
not in ( -- recreate the results from the first half of the union
select concat(c.category,'x',min(c.value))
from zzz c
group by c.category
)
group by second_smallest.category
order by category
Предостережения:
Ваш пробег может отличаться,
- Mark
SELECT c1.category, c1.value
FROM catvals c1
LEFT OUTER JOIN catvals c2
ON (c1.category = c2.category AND c1.value > c2.value)
GROUP BY c1.category, c1.value
HAVING COUNT(*) < 2;
Протестировано на MySQL 5.1.41 с вашими тестовыми данными. Вывод:
+----------+-------+
| category | value |
+----------+-------+
| 1 | 1.30 |
| 1 | 1.60 |
| 2 | 9.20 |
| 2 | 9.50 |
| 3 | 4.00 |
| 3 | 8.00 |
+----------+-------+
(Дополнительные десятичные разряды вызваны тем, что я объявил столбец значение
как NUMERIC (9,2)
.)
Как и другие решения, это дает больше 2 строк по категории, если есть связи. Есть способы создать условие соединения, чтобы решить эту проблему, но нам нужно будет использовать первичный ключ или уникальный ключ в вашей таблице, и нам также нужно будет знать, как вы намереваетесь разрешить связи. .
Вот очень обобщенное решение, которое будет работать для выбора первых n строк для каждой категории. Это будет работать, даже если есть повторяющиеся значения.
/* creating temporary variables */
mysql> set @cnt = 0;
mysql> set @trk = 0;
/* query */
mysql> select Category, Value
from (select *,
@cnt:=if(@trk = Category, @cnt+1, 0) cnt,
@trk:=Category
from user_categories
order by Category, Value ) c1
where c1.cnt < 2;
Вот результат.
+----------+-------+
| Category | Value |
+----------+-------+
| 1 | 1.3 |
| 1 | 1.6 |
| 2 | 9.2 |
| 2 | 9.5 |
| 3 | 4 |
| 3 | 8 |
+----------+-------+
Проверено на MySQL 5.0.88 Обратите внимание, что начальное значение переменной @trk не должно быть наименьшим значением поля Категория.