MySQL / PHP - подсчет нескольких переменных в части WHERE оператора SELECT

У меня есть следующий оператор PHP / MySQL:

$varTemp = mysqli_num_rows(mysqli_query($connect,"SELECT * FROM table WHERE
(Date1 BETWEEN '2017-10-01' AND '2017-10-31' AND marker = 'Post' AND grade1 > 224) OR
(Date2 BETWEEN '2017-10-01' AND '2017-10-31' AND marker = 'Post' AND grade2 > 224) OR
(Date3 BETWEEN '2017-10-01' AND '2017-10-31' AND marker = 'Post' AND grade3 > 224) OR
(Date4 BETWEEN '2017-10-01' AND '2017-10-31' AND marker = 'Post' AND grade4 > 224)"));

Прямо сейчас между операторами стоит OR. Я также пробовал UNION и +, но получаю тот же результат. Этот оператор ДОЛЖЕН возвращать 20 записей, но он дает мне только 18, потому что есть два человека, которые находятся в обоих операторах «Date1» и «Date2».

У меня такой вопрос: как мне изменить этот оператор, чтобы подсчитать эти повторяющиеся записи?

Соединение Date1 и grade1 похоже на то, что дизайн БД, вероятно, следует пересмотреть. Может быть, эти столбцы семестровые? Если это так, я бы добавил семестровую колонку, тогда это можно было бы легко сделать с помощью where date BETWEEN '2017-10-01' AND '2017-10-31' AND marker = 'Post' AND grade > 244 and semester between 1 and 4.

user3783243 25.07.2018 17:20

См .: Почему я должен предоставлять MCVE для того, что мне кажется очень простым запросом SQL? - хотя, как предполагает user3783243, проблема такого рода действительно свидетельствует о плохом дизайне.

Strawberry 25.07.2018 17:37

Для каждого человека собирается до 4 дат, и каждой дате соответствует оценка. Что вы предлагаете в качестве альтернативного дизайна? [пожалуйста, не воспринимайте это как язвительный вопрос, мне интересно узнать, есть ли лучший способ сделать это]

Mr_Thomas 25.07.2018 17:43
Стоит ли изучать PHP в 2026-2027 годах?
Стоит ли изучать PHP в 2026-2027 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Symfony Station Communiqué - 7 июля 2023 г
Symfony Station Communiqué - 7 июля 2023 г
Это коммюнике первоначально появилось на Symfony Station .
Оживление вашего приложения Laravel: Понимание режима обслуживания
Оживление вашего приложения Laravel: Понимание режима обслуживания
Здравствуйте, разработчики! В сегодняшней статье мы рассмотрим важный аспект управления приложениями, который часто упускается из виду в суете...
Установка и настройка Nginx и PHP на Ubuntu-сервере
Установка и настройка Nginx и PHP на Ubuntu-сервере
В этот раз я сделаю руководство по установке и настройке nginx и php на Ubuntu OS.
Коллекции в Laravel более простым способом
Коллекции в Laravel более простым способом
Привет, читатели, сегодня мы узнаем о коллекциях. В Laravel коллекции - это способ манипулировать массивами и играть с массивами данных. Благодаря...
Как установить PHP на Mac
Как установить PHP на Mac
PHP - это популярный язык программирования, который используется для разработки веб-приложений. Если вы используете Mac и хотите разрабатывать...
1
3
46
3
Перейти к ответу Данный вопрос помечен как решенный

Ответы 3

Ответ принят как подходящий

Природа OR требует, чтобы запись учитывалась только один раз, независимо от того, сколько частей предложения WHERE совпадают. Если вы хотите дважды подсчитать записи, которые находятся в нескольких диапазонах, вы на правильном пути с UNION. Однако UNION по умолчанию удаляет дубликаты, что дает тот же результат, что и OR. В вашем случае вы, вероятно, захотите использовать UNION ALL, который аналогичен UNION, но не удаляет дубликаты.

У вас есть ошибка в вашей логике, чтобы получить результат, который вы ищете, вам нужно будет выполнить несколько запросов, при этом OR в вашем предложении WHERE просто говорит, что если это произойдет, поместите это в результат, это фильтр, поэтому он не изменять количество записей в таблице самостоятельно.

вам нужно будет сделать что-то вроде этого:

SELECT * FROM table WHERE SELECT * FROM table WHERE
    (Date1 BETWEEN '2017-10-01' AND '2017-10-31' AND marker = 'Post' AND grade1 > 224)
UNION ALL
SELECT * FROM table WHERE SELECT * FROM table WHERE
    (Date2 BETWEEN '2017-10-01' AND '2017-10-31' AND marker = 'Post' AND grade2 > 224)

и повторите для каждого из ваших «ИЛИ», вот как вы можете дублировать записи.

Обратите внимание, что ваш запрос функционально идентичен ...

SELECT * 
  FROM table 
 WHERE 
     ( Date1 BETWEEN '2017-10-01' AND '2017-10-31' 
    OR Date2 BETWEEN '2017-10-01' AND '2017-10-31' 
    OR Date3 BETWEEN '2017-10-01' AND '2017-10-31' 
    OR Date4 BETWEEN '2017-10-01' AND '2017-10-31'
     )         
   AND marker = 'Post' 
   AND 224 IN(grade1,grade2,grade3,grade4)

... но если бы у меня был такой запрос, я бы переделал свою таблицу.

Другие вопросы по теме