Как мне использовать другой столбец, если две строки в первом отмеченном столбце совпадают?

#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 .