Подзапрос в PHP - PullRequest
       45

Подзапрос в PHP

2 голосов
/ 14 января 2011

Давайте приведем простой пример с двумя таблицами:

USERS (Id, Name, City)
PLAYERS (Id_Player, Number, Team)

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

Я объясняю. Что работает, но не оптимизировать:

for($i=0;$i<something;$i++)
{
    $res2=mysql_query("SELECT Team from PLAYERS WHERE Number=$i 
        AND Id_Player IN (SELECT Id FROM USERS WHERE City='London')");
}

Что бы я хотел сделать, но это не сработало:

$res1=mysql_query("SELECT Id from USERS where City='London'");
for($i=0;$i<something;$i++)
{
    $res2=mysql_query("SELECT Team from PLAYERS WHERE Number=$i 
        AND Id_Player IN **$res1**");
}

Спасибо!

Ответы [ 5 ]

2 голосов
/ 14 января 2011

Нечто подобное должно работать.

<?
$sql = "SELECT Team from PLAYERS 
    JOIN USERS on (Id_player=Id)
    WHERE Number BETWEEN $minID AND $maxID
    AND City='London'
    GROUP BY Team";

$results=mysql_query($sql) or die(mysql_error());


// $results contain all the teams from London
// Use like normal..

echo "<ul>\n";

while($team = mysql_fetch_array($results)){
    echo "\t<li>{$team['Team']}</li>\n";
}

echo "</ul>";
2 голосов
/ 14 января 2011

Размещение запросов SQL в циклах может быть очень медленным и занимать много ресурсов, обратите внимание на использование JOIN в вашем SQL.Это не так сложно, и как только вы освоите его, вы можете написать действительно быстрый мощный SQL.

Вот хороший учебник, который стоит взглянуть на различные типы JOIN:
http://www.keithjbrown.co.uk/vworks/mysql/mysql_p5.php

2 голосов
/ 14 января 2011

SELECT PLAYERS.*, USERS.City FROM PLAYERS, USERS WHERE USERS.City='London' AND PLAYERS.Number = $i

Не лучший способ сделать это; может быть LEFT JOIN, но это должно работать. Возможно, синтаксис неправильный.

Джеймс

EDIT

ВНИМАНИЕ: Это не самое идеальное решение. Пожалуйста, дайте мне более конкретный запрос, и я могу отсортировать запрос join для вас.

Принимая во внимание ваш комментарий, давайте рассмотрим другой пример. Это позволит использовать PHP для создания списка, который мы можем использовать с ключевым словом MySQL IN.

Сначала сделайте запрос:

$res1 = mysql_query("SELECT Id from USERS where City='London'");

Затем выполните цикл запроса и поместите каждое Id поле одно за другим в список через запятую:

$player_ids = "";

while($row = mysql_fetch_array($res1))
{
    $player_ids .= $row['Id'] . ",";
}

$player_ids = rtrim($player_ids, ",");

Теперь у вас должен быть список идентификаторов, подобных этому:

12, 14, 6, 4, 3, 15, ...

Теперь, чтобы поместить его во второй запрос:

for($i = 0; $i<something; $i++) 
{      
    $res2 = mysql_query("SELECT Team from PLAYERS WHERE Number=$i          
    AND Id_Player IN $player_ids"); 
}

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

Если вы хотите составить список строк, а не идентификаторов или других чисел, измените первый цикл while, заменив строку внутри него на

$player_ids .= "'" . $row['Id'] . "',";

Если бы вы могли дать мне ваш фактический запрос, который вы используете, я могу придумать что-нибудь получше; как я сказал выше, это более общий способ ведения дел, не обязательно лучший.

1 голос
/ 14 января 2011
$res1=mysql_query("SELECT Id from USERS where City='London'");
for($i=0;$i<something;$i++)
{
    $res2=mysql_query("SELECT Team from PLAYERS WHERE Number=$i 
        AND Id_Player IN **$res1**");
}

Работает, но mysql_query() возвращает РУЧКУ РЕЗУЛЬТАТА. Он не возвращает значение id. Любой запрос выбора, независимо от того, сколько строк он возвращает, возвращает оператор результата, а не значение. Сначала вы должны извлечь строку, используя один из вызовов mysql_fetch...(), который возвращает эту строку, из которой вы затем можете извлечь значение id. так что ...

$stmt = mysql_query("select ID ...");
if ($stmt === FALSE) {
    die(msyql_error());
}
if ($stmt->num_rows > 0) {
    $ids = array();
    while($row = mysql_fetch_assoc($stmt)) {
        $ids[] = $row['id']
    }
    $ids = implode(',', $ids)
    $stmt = mysql_query("select TEAM from ... where Id_player IN ($ids)");
    .... more fetching/processing here ...
}
1 голос
/ 14 января 2011

Выполнение запроса в цикле не очень хорошая идея. Гораздо лучше было бы получить всю таблицу, а затем перебрать таблицу в цикле.

Таким образом, запрос будет выглядеть примерно так:

"SELECT Team from PLAYERS WHERE Number BETWEEN($id, $something) 
        AND Id_Player IN (SELECT Id FROM USERS WHERE City='London')"
...