0
我有一個存儲的一切副本數據庫,我們需要能夠只提取1的這個副本。該表是:PHP/MySQL的越來越每隔一行在表中的問題/停止添加記錄兩次
+----+------------+-----------+-------------+
| id | locationId | name | description |
+----+------------+-----------+-------------+
| 1 | 1 | rgh | lol |
| 2 | 1 | rgh | lol |
| 3 | 2 | tbh | gjbh |
| 4 | 2 | tbh | gjbh |
| 5 | 3 | lolcbj999 | abububh |
| 6 | 3 | lolcbj999 | abububh |
| 7 | 4 | test | vhjj |
| 8 | 4 | test | vhjj |
| 9 | 5 | ghh | yhhh |
| 10 | 5 | ghh | yhhh |
+----+------------+-----------+-------------+
我們使用%2 == 0的方法嘗試,但問題是,注意locationId是怎樣一個外鍵到這個表
+----+--------+-----------+-----------+-----------+
| id | walkId | longitude | latitude | timestamp |
+----+--------+-----------+-----------+-----------+
| 1 | 1 | -4.067431 | 52.416904 | 2 |
| 2 | 2 | -4.067398 | 52.416908 | 0 |
| 3 | 3 | -4.067419 | 52.416904 | 3 |
| 4 | 4 | -4.067482 | 52.416897 | 1 |
| 5 | 5 | -4.067458 | 52.416897 | 1 |
+----+--------+-----------+-----------+-----------+
我們希望在顯示此內容一個XML文件,那麼我們該怎麼做呢?基於事實。我們似乎無法理解這一點,我們可以返回所有賠率,所以wlak id 1,3,5但是錯過2和4,反之亦然。有任何想法嗎?
我們寧願它,如果有一種方法來阻止如果這樣使用這個數據庫,PHP代碼做什麼,我們需要改變被添加兩次記錄:
<?php
/**
* This file contains database related functions.
*
* @file
*/
# prevent users from accessing this page via their browser
if (!defined('ENTRYPOINT')) {
die('This is not a valid entry point.');
}
require dirname(__FILE__) . '/../config.php';
/**
* This function runs the query that will attempt to create the correct tables
* in the database.
*
* @return a string detailing errors encountered, or FALSE if the query worked.
*/
function createDatabase() {
$db = openConnection();
$sql = <<<'SQL'
CREATE TABLE tbl_routes (
id int NOT NULL AUTO_INCREMENT, title varchar(255), shortDesc varchar(255), longDesc varchar(255),
hours float(12), distance float(12), PRIMARY KEY (id));
CREATE TABLE tbl_locations (
id int NOT NULL AUTO_INCREMENT, walkId int NOT NULL, latitude float(12), longitude float(12), timestamp float(12),
PRIMARY KEY (id), FOREIGN KEY (walkId) REFERENCES tbl_routes(id));
CREATE TABLE tbl_places (
id int NOT NULL AUTO_INCREMENT, locationId int NOT NULL, description varchar(255),
PRIMARY KEY (id), FOREIGN KEY (locationId) REFERENCES tbl_locations(id));
CREATE TABLE tbl_images (
id int NOT NULL AUTO_INCREMENT, placeId int NOT NULL, photoName varchar(255),
PRIMARY KEY (id), FOREIGN KEY (placeId) REFERENCES tbl_places(id));
SQL;
$query = executeSql($sql);
if (!is_string($query)) {
return FALSE;
} else {
return $query;
}
}
/**
* This function inputs a walk into the database.
*
* @param a walk object, as created by the upload.php function
* @return a string describing the error, or SUCCESS if things worked
*/
function inputWalk($walk) {
# TODO
# we need to escape the inputs to proof against SQL injections
# see rfc 4389 2.5.2
$values = [
"NULL", # ID is assigned by the database thanks to AUTO_INCREMENT
"'$walk->title'",
"'$walk->shortDesc'",
"'$walk->longDesc'",
"NULL",
"NULL"
];
$sql = 'INSERT INTO tbl_routes VALUES (' . implode($values, ',') . ');';
$db = openConnection();
$query = mysqli_query($db, $sql);
if (is_bool($query) && $query === TRUE) {
# the SQL query worked and the data is stored
# we need to request the data back to see what the ID has been set to
$walkId = mysqli_insert_id($db);
foreach ($walk -> locations as &$location) {
$query = null;
$values = null;
$values = [
"NULL", # location ID
$walkId,
"'" . mysqli_real_escape_string($db, $location->latitude) . "'",
"'" . mysqli_real_escape_string($db, $location->longitude) . "'",
"'" . mysqli_real_escape_string($db, $location->timestamp) . "'"
];
$query = "INSERT INTO tbl_locations VALUES (" . implode($values, ',') . ");";
$sql = mysqli_query($db, $query);
if ($sql === FALSE) { return $query; }
# now need to get the locationId
$locID = mysqli_insert_id($db);
foreach ($location -> descriptions as &$description) {
$description[0] = mysqli_real_escape_string($db, $description[0]);
$description[1] = mysqli_real_escape_string($db, $description[1]);
# TODO: BUG: doesn't actually work...
$sql = "INSERT INTO tbl_places VALUES (NULL, '$locID', '$description[0]', '$description[1]');";
$query = mysqli_query($db, $sql);
if ($query === FALSE) { return mysqli_error($db); }
}
foreach ($location -> images as &$image) {
$query = "INSERT INTO tbl_images VALUES (NULL, $locID, '$image[0]');";
mysqli_query($db, $sql);
}
}
# everything worked
return 'SUCCESS'; # TODO: make this less hackish
} else {
return $query;
}
}
/**
* This function opens a connection to the database.
* @return an active database connection.
*
* Use closeConnection() to close it again.
*/
function openConnection() {
global $DB_ADDR, $DB_USER, $DB_PASS, $DB_NAME;
$db = mysqli_connect($DB_ADDR, $DB_USER, $DB_PASS, $DB_NAME);
if (!$db) {
# connection failed
die('Could not connect to MySQL');
}
return $db;
}
/**
* Executes an SQL statement.
* @param the SQL to execute
* @return the result of the action
*
* On success it will return a mysqli_result() object when the SQL statement is
* a SELECT, SHOW, DESCRIBE or EXPLAIN. Other successes will return TRUE.
*
* Failures will return a string explaining the error. Use is_object() to
* discern between the error string and a result.
*/
function executeSql($sql) {
$db = openConnection();
$query = mysqli_query($db, $sql);
if ($query === FALSE) {
$query = mysqli_error($db);
}
closeDatabase($db);
return $query;
}
/**
* Closes an active database connection.
* @param the database connection to close.
*/
function closeDatabase($db) {
mysqli_close($db);
}
/**
* Fetches the first field of the first row of a result
* @param The result to fetch
* @return the first field of the first row
* @deprecated
*/
function fetchID(mysqli_result $result) {
return $result->fetch_row()[0];
}
乾杯, 克里斯。
[觀察每組的問題及答案的ROWNUMBER(http://stackoverflow.com/questions/17939198/row-number-per-group-in-mysql),你可以把一個子查詢,只有選擇rownumber = 1變體。 – Wrikken
按照locationId,名稱和說明進行分組。把每一行都拉出來似乎是合乎邏輯的,但是當重複的行不相鄰時,會發生什麼?如果您有大量的行,子查詢可能會更好。您需要測試以查看哪個更快。 – Dave
GROUP BY會更好,你會用子查詢重新選擇*每行*,這是非常低效的。 – MackieeE