Сочетание MySQL, PHP и вложенных запросов с проблемами результатов

У меня проблема с каким-то кодом, над которым я работаю, и который предназначен для этой цели: во-первых, он извлекает все записи с одинаковым идентификатором компании и загрузками типов из одной таблицы, затем сравнивает результаты с записи во второй таблице. Обычно это не проблема для меня … просто.

Тем не менее, моя проблема заключается в нескольких факторах: запросы поступают из ряда классов. Это основная используемая функция:

public function query($query, $params = array())
{
try {
//$query = $this->build_query($query, $table);
$params = $this->build_params($params);
$params = $this->clean_params($query, $params);
$this->lastquery = $this->pdo->prepare($query);
//$this->lastquery->bindParam(':table', $this->DBPrefix . $table, PDO::PARAM_STR); // must always be set
foreach ($params as $val)
{
$this->lastquery->bindParam($val[0], $val[1], @$val[2]);
}
$this->lastquery->execute();
//$this->lastquery->debugDumpParams();
}
catch(PDOException $e) {
//$this->lastquery->debugDumpParams();
$this->error_handler($e->getMessage());
}

//$this->lastquery->rowCount(); // rows affected
}

Теперь это код, который я получил. Обратите внимание, что перед этим указывается company_id, $ DBPrefix определяется как префикс, используемый во всех таблицах базы данных. О, и пока игнорируйте параметры … Я еще не включил эту часть, но это будет сделано:

unlink($includeFile);
//Start Scan Procedures
//Step one - Read all records with type "uploads" & company_id that match current company_id
$query =    "SELECT property_id, account_id, company_id, description, pict_url, photo_uploaded, bed,
bath, sqft, built, embed_url, ext_tour_url, street, city, state, zip, unit, agent,
lat, lng, mlsid, ptype, pets, furnished, length, security_deposit, pet_deposit,
filename, created, type, status
FROM " . $DBPrefix . "properties_uploads
WHERE company_id = " . $company_id . "AND type = 'uploads'";
$db->query($query);
$rec_to_upload = $db->result();
$count_uploads = 0;
foreach ($rec_to_upload as $rec) {
$query =    "SELECT property_id
FROM " . $DBPrefix . "properties
WHERE company_id = " . $company_id . "AND street = '" . $rec['street'] . "'
AND city = '" . $rec['city'] . "'
AND state = '" . $rec['state'] . "'
AND unit = '" . $rec['unit'] . "'";
if ($db->numrows() == 0) {
//update to be an original type
$query =    "UPDATE " . $DBPrefix . "properties_uploads
SET type = 'original'
WHERE property_id = " . $rec['property_id'];
$db->query($query);
$count_uploads++;
} else {
//update to be a duplicate type
$query =    "UPDATE " . $DBPrefix . "properties_uploads
SET type = 'duplicate'
WHERE property_id = " . $rec['property_id'];
$db->query($query);
}
}

Когда я выполняю запросы SQL через MYSQL самостоятельно, они работают отлично … и я каждый раз получаю правильные ответы.

Однако, когда я проверяю это, результаты $ rec_to_upload возвращаются как одна запись, а не как 9, которая должна отображаться. Он не запускает цикл foreach более одного раза. Если я запускаю функцию numrows, мы должны определить количество строк, это верно для первого запроса, но он сохраняет свой результат в первый раз для внутреннего запроса, затем переходит к 0 и возвращает от 0 до 1. Таблица свойств пусто, поэтому должно быть 0 на всем протяжении.

Я не могу сделать $ rec [‘city’], потому что он запускает только одну запись. Если я сделаю $ rec_to_upload [‘city’], то получится результат, но это все еще не решение для нескольких записей.

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

Наконец, результаты первого запроса, кажется, продвигаются дважды: я получаю как ассоциативные, так и числовые результаты.

Заранее благодарю за любую помощь, которую вы можете оказать. Если у вас есть какие-либо вопросы, которые помогут уточнить, я более чем рад ответить на них.


Дополнительная информация. Это начинается с первого запроса с проблемами. Я сделал резервную копию, затем очистил все после SQL, пока я не остался с этим:

//Start Scan Procedures
//Step one - Read all records with type "uploads" & company_id that match current company_id
$query =    "SELECT property_id, account_id, company_id, description, pict_url, photo_uploaded, bed,
bath, sqft, built, embed_url, ext_tour_url, street, city, state, zip, unit, agent,
lat, lng, mlsid, ptype, pets, furnished, length, security_deposit, pet_deposit,
filename, created, type, status
FROM " . $DBPrefix . "properties_uploads
WHERE company_id = " . $company_id . "AND type = 'uploads'";
$db->query($query);
$rec_to_upload = $db->result();
$i = 1;
foreach ($rec_to_upload as $rtu) {
echo $i . '<br>';
$i++;
}
echo $db->numrows();

Результаты: записано 62 записи. 9 записей и 30 столбцов. Похоже, что он прошел и поместил одну запись в поле за полем с полями в виде отдельных записей … как ассоциативных, так и числовых, вместо того, чтобы вводить строки в.

-1

Решение

Учтите следующее. Указанное мною требование немного отличается от вашего, но я думаю, что принцип остается прежним:

DROP TABLE IF EXISTS my_table;

CREATE TABLE my_table
(id INT NOT NULL AUTO_INCREMENT PRIMARY KEY
,name VARCHAR(12) NOT NULL
,type VARCHAR(20) NOT NULL
);

INSERT INTO my_table VALUES
(1,'Adam','unreconciled'),
(2,'Ben','reconciled'),
(3,'Charlie','reconciled'),
(4,'Adam','unreconciled'),
(5,'Ben','unreconciled'),
(6,'Dan','unreconciled');SELECT * FROM my_table;
+----+---------+--------------+
| id | name    | type         |
+----+---------+--------------+
|  1 | Adam    | unreconciled |
|  2 | Ben     | reconciled   |
|  3 | Charlie | reconciled   |
|  4 | Adam    | unreconciled |
|  5 | Ben     | unreconciled |
|  6 | Dan     | unreconciled |
+----+---------+--------------+

SELECT x.*
, CASE WHEN y.id IS NOT NULL THEN 'duplicate' ELSE 'original' END type
FROM my_table x
LEFT
JOIN my_table y
ON y.name = x.name
AND y.id < x.id
WHERE x.type = 'unreconciled';

+----+------+--------------+-----------+
| id | name | type         | type      |
+----+------+--------------+-----------+
|  1 | Adam | unreconciled | original  |
|  4 | Adam | unreconciled | duplicate |
|  5 | Ben  | unreconciled | duplicate |
|  6 | Dan  | unreconciled | original  |
+----+------+--------------+-----------+UPDATE my_table x
LEFT
JOIN my_table y
ON y.name = x.name
AND y.id < x.id
SET x.type = CASE WHEN y.id IS NOT NULL THEN 'duplicate' ELSE 'original' END
WHERE x.type = 'unreconciled';
Query OK, 4 rows affected (0.04 sec)

SELECT * FROM my_table;
+----+---------+------------+
| id | name    | type       |
+----+---------+------------+
|  1 | Adam    | original   |
|  2 | Ben     | reconciled |
|  3 | Charlie | reconciled |
|  4 | Adam    | duplicate  |
|  5 | Ben     | duplicate  |
|  6 | Dan     | original   |
+----+---------+------------+

Это соответствует всего одному запросу. Не 2 запроса, не 3 запроса, не 1 запрос на цикл. Всего 1 запрос. Если вы сможете адаптировать это к своей цели, это будет на несколько порядков быстрее, чем ваше настоящее решение.

1

Другие решения

Задача решена!

Что я сделал, учитывая, что он перезаписывал результат $ db->, так это попытался предотвратить его несколькими способами … пытаясь заполнить массив. Я наконец преуспел, просто делая:

while ($row = $db->result()) {
$prop_data[] = $row;
}

и затем идти оттуда. Спасибо всем, кто пытался помочь!

0

По вопросам рекламы [email protected]