#mysql #sql
#mysql #sql
Вопрос:
У меня есть таблица, которая выглядит примерно так:
камни
ID | число | snumber | wt | qt |
---|---|---|---|---|
1 | a | 11.5 | 13 | |
2 | c | 4.0 | 8 | |
3 | a | a1 | 1.0 | 2 |
4 | d | 0.5 | 1 | |
5 | b | 2.0 | 4 | |
6 | a | a2 | 5.0 | 1 |
7 | f | 3.0 | 6 | |
8 | a | a3 | 5.0 | 10 |
Как мне выбрать все из stones и если в столбце number есть строки в столбце, snumber выдает результаты только из строк snumber [в противном случае используйте number]?
Я также пытаюсь включить в свой предыдущий [рабочий] код, который выбирает все строки в таблице с wt> = 2.5, а затем подсчитывает все эти строки как totalrows:
SELECT inv.*, COUNT(*) OVER() AS totalrows FROM stones inv WHERE wt >= 2.5
- Итак, из приведенного выше примера я бы хотел показать следующие строки c, a2, f и a3 с totalrows = 4:
ID | число | snumber | wt | qt | totalrows |
---|---|---|---|---|---|
2 | c | 4.0 | 8 | 4 | |
6 | a | a2 | 5.0 | 1 | 4 |
7 | f | 3.0 | 6 | 4 | |
8 | a | a3 | 5.0 | 10 | 4 |
Неудачная попытка
Я пробовал это, но я получаю ошибку с моим PHP, поэтому я предполагаю, что проблема с SQL:
1-й
SELECT stones.*,
CASE
WHEN x.totalrows > 1
THEN stones.snumber
ELSE stones.number
END AS numberORsnumber
FROM stones
JOIN (
SELECT number, COUNT(*) AS totalrows FROM stones
GROUP BY number
) x ON x.number = stones.number
WHERE x.totalrows = 1 OR stones.snumber <> '' AND wt >= 2.5
2-й
SELECT inv.*, COUNT(*) OVER() AS totalrows FROM stones inv
CASE
WHEN totalrows > 1
THEN inv.snumber
ELSE inv.number
END AS number
WHERE wt >= 2.5
Комментарии:
1. Смотрите COALESCE () и используйте NULL для пустых значений
2. @Strawberry На самом деле я просто смотрел на это, но я хочу использовать number , если другие строки с этим номером не имеют snumber, и в этом случае используйте только этот snumber , а не «главный» номер . Я не мог понять, как это проверить
COALESCE()
.3. 2-я попытка неверна. Вы делали
FROM stones inv
, чтобыCASE ..
. Должно быть наоборот. ЕслиCASE
выражение перемещено вSELECT
, вы не можете фактически использоватьtotalrows
в операции. Если вы не делаете это как подзапрос, то используетеtotalrows
во внешнем запросеSELECT
Ответ №1:
Ошибка находится на END AS number OR snumber
. После удаления OR snumber
ошибки не будет, но и результата тоже не будет; по сравнению с приведенными вами примерами данных. Попробуйте изменить WHERE x.totalrows = 1 AND wt >= 2.5
на WHERE wt >= 2.5
только потому, что вы уже выполняете CASE
выражение:
CASE
WHEN x.totalrows > 1
THEN stones.snumber
ELSE stones.number
END AS number
Таким образом, добавление WHERE x.totalrows = 1
ничего не даст из CASE
.
Обновить:
Что ж, после долгого обсуждения в комментариях, я думаю, что понял это:
SELECT inv.ID,
CASE WHEN inv.snumber <> ""
THEN inv.snumber ELSE inv.number
END AS numberORSnumber,
inv.wt,
inv.qt,
COUNT(*) OVER() AS totalrows,
CASE WHEN inv.number=v.number
AND inv.snumber="" THEN 0 ELSE 1 END AS Checking
FROM stones inv
CROSS JOIN
(SELECT number FROM stones WHERE snumber <> "" group by number) v
WHERE wt >= 2.5
HAVING Checking <> 0
ORDER BY ID ASC;
В итоге я добавляю a CROSS JOIN
с подзапросом, который возвращает number
значение, snumber
соответствующее требованию OP. Затем с помощью этого я использую CASE
для проверки и, наконец, использую HAVING
для отфильтровывания их из проверки.
https://dbfiddle.uk/?rdbms=mysql_8.0amp;fiddle=40cb88da028a42dc147dc4224154ab05
Комментарии:
1. Вау, это в значительной степени то, что я хочу! Есть ли какой-либо способ объединить подсчет totalrows с остальной частью SQL?
2. Я не уверен, что вы имеете в виду. Условие
wt >= 2.5
в значительной степени ограничивает результаты этим условием на данный момент. Вы пытаетесь вернуть все изstones
таблицы и добавить дополнительные столбцы из результатов запроса? АLEFT JOIN
может быть? Можете ли вы отредактировать свой вопрос и опубликовать ожидаемый результат? Спасибо3. Я добавил еще одну таблицу в тело вопроса, объясняющую, что я хочу. Кстати, спасибо за ваше время
4. На самом деле результаты подсчета — это все
5
.. и я думаюwt >= 2.5
, что здесь нельзя использовать. Как получить count = 6?5. OMG, я так сожалею об этом. Я исправил это до правильных желаемых результатов. Я сделал это слишком быстро. Неужели нет способа сделать это? Я также должен добавить несколько
AND
s послеwt >= 2.5
.