Я действительно не решаюсь публиковать ответ, так как SQL здесь вызывает все виды дополнительной работы, которую вы делаете в PHP.Без схемы БД и некоторых примеров данных я чувствую, что просто ослеп.Например, что все эти DISTINCT
вещи делают здесь, может быть, они нужны, может быть, они лишние ... У меня нет способа узнать.
То, что здесь сказано,
Это все одна и та же таблица, поэтому нет смысла снова запрашивать одни и те же данные. Возьмем, к примеру, эти 2 запроса
$customers = "SELECT DISTINCT customer_name FROM `wo_main_alldata` WHERE ship_date BETWEEN '$twoYearsAgo' AND '$currentDate'";
$laneData = "SELECT DISTINCT type_of_shipment, pickup_city, pickup_state, consignee_city, consignee_state
FROM wo_main_alldata
WHERE customer_name = '$customerName'
AND pickup_city != ''";
. Вы можете объединить их примерно так:
$laneData = "SELECT DISTINCT
customer_name, -- From the first query
type_of_shipment,
pickup_city,
pickup_state,
consignee_city,
consignee_state
FROM
wo_main_alldata
WHERE
ship_date BETWEEN '$twoYearsAgo' AND '$currentDate'
AND
pickup_city != ''
";
Первый запрос извлекает все «отличительные» имена клиентов, затем вы перебираете их и используете это имя для поиска следующего набора данных в той же таблице.
Этот поиск аннулирует то, что вы использовали в первом, но (да) он у вас есть и здесь.Это аннулирует это, потому что второй запрос говорит: «Дайте мне все записи, где customer_name = что-то», так что, если имя присутствует там многократно, вы найдете все те со вторым запросом.Различия, возможно, были важны, когда они были отдельными, чтобы контролировать цикл foreach ($customerList as $customerName){
.Но нам больше не нужен этот цикл.
Когда мы объединяем их, мы добавляем customer_name
к выбору второго, а также добавляем биты WHERE
. Затем мы можем удалить условие, чтосвязали их вместе customer_name = '$customerName'
, потому что он нам больше не нужен, так как он становится customer_name=customer_name
, который является просто "этим рядом".
Теперь это выглядит не намного чище.Также устраняется весь этот код:
$customers = "SELECT DISTINCT customer_name FROM `wo_main_alldata` WHERE ship_date BETWEEN '$twoYearsAgo' AND '$currentDate'";
$customerResult = mysqli_query($conn, $customers);
$customerList= array();
while ($row = mysqli_fetch_array($customerResult)) {
$customerList[] = $row[0];
}
$lanesArray = array();
foreach ($customerList as $customerName){
$laneData = "SELECT DISTINCT type_of_shipment, pickup_city, pickup_state, consignee_city, consignee_state
FROM wo_main_alldata
WHERE customer_name = '$customerName'
AND pickup_city != ''";
Оба выбирают данные из одной таблицы, вторая (в цикле) просто берет имя пользователя из первого запроса и снова ищет его в той же таблице.,
В последнем запросе вы (опять) просто снова ссылаетесь на те же данные
$equipment = $row2[0]; //from previous query on same table
WHERE type_of_shipment = '$equipment'
Все содержимое условия where напрямую связано с результатами другого запроса, поэтому выможет просто устранить это.И это оставляет нас с этим:
SELECT
AVG(f.proj_revenue),
AVG(f.proj_gross_profit),
COUNT(f.pro_num)
FROM (
SELECT DISTINCT
customer_name,
type_of_shipment,
pickup_city,
pickup_state,
consignee_city,
consignee_state
FROM
wo_main_alldata
WHERE
ship_date BETWEEN '$twoYearsAgo' AND '$currentDate' -- From the first query
AND
pickup_city != ''
) as f
Я не могу на самом деле проверить это, поэтому вам, возможно, придется внести некоторые коррективы, я просто чувствую свой путь, хотя логика этого.Я почти уверен, что столбцы в запросе верхнего уровня также должны быть во внутреннем подзапросе.В частности f.proj_revenue
, f.proj_gross_profit
и f.pro_num
.Вероятно, вы получите что-то вроде Unknown column 'f.proj_gross_profit' in 'field list'
Есть несколько способов исправить это, снова присоединившись к столу.
SELECT
AVG(m.proj_revenue),
AVG(m.proj_gross_profit),
COUNT(m.pro_num)
FROM
wo_main_alldata AS m
JOIN
(
SELECT DISTINCT
id, //<--- id is an issue
customer_name,
type_of_shipment,
pickup_city,
pickup_state,
consignee_city,
consignee_state
FROM
wo_main_alldata
JOIN
WHERE
ship_date BETWEEN '$twoYearsAgo' AND '$currentDate'
AND
pickup_city != ''
) as f
ON f.id = m.id
Я не совсем уверен, что лучше всего обойти это, поскольку я не знаю, что должно быть отчетливым.Это действительно усложняет ситуацию, потому что если вы введете идентификатор, как указано выше, это может отравить ваш отдельный вызов, будучи уникальным для каждой строки.Вы можете сделать все это одним запросом:
SELECT DISTINCT
customer_name,
type_of_shipment,
pickup_city,
pickup_state,
consignee_city,
consignee_state,
AVG(m.proj_revenue),
AVG(m.proj_gross_profit),
COUNT(m.pro_num)
FROM
wo_main_alldata
WHERE
ship_date BETWEEN '$twoYearsAgo' AND '$currentDate'
AND
pickup_city != ''
Но это слишком абстрактно, чтобы я мог это сказать.Не бойтесь взять PHPmyAdmin (или то, чем вы управляете БД) и работать над запросом прямо там.Таким образом, вы можете поиграть с ним вне какого-либо кодирования и получить его так, как вам хочется.
В любом случае, если вы обнаружите, что совершаете обходы в БД для тех же данных, скорее всего, вы можете это сделатьв одном немного более сложном запросе.Заманчиво, если вы плохо знаете SQL, но в PHP справедливо просто делать простые запросы и работать с ним в PHP.
Сначала это кажется «легким» способом, но каждая часть работы, которую вы можете выполнять с БД, экономит 2 или 3 части работы в PHP.Ваш код будет меньше, легче, проще и легче для чтения.Например (при условии, что вы можете комбинировать их, как предложено), ваш код становится таким:
$lanesAverageResult = mysqli_query($conn, $laneAverages); //our new query
while ($row3 = mysqli_fetch_array($lanesAverageResult)){
}
Таким образом, мы просто исключили 25+
строк PHP с помощью немного более сложного запроса.
PS извините, это так долго ..
Надеюсь, это поможет!