Laravel - запрос WhereRaw CAST не работает в цикле while - PullRequest
0 голосов
/ 01 февраля 2020

У меня есть запрос SQL, где я преобразую столбец в SIGNED, чтобы сравнить его с целым числом. Моя таблица "Планеты" выглядит следующим образом

id | name | galaxy | region
1  | S1   | 00     | 01
2  | S2   | 00     | 01
3  | S3   | 00     | 02
4  | S4   | 01     | 00
5  | S5   | 00     | 00

Существуют сотни записей, принадлежащих разным галактикам (0-99) и регионам (0-99)

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

У меня есть переменная, как показано ниже

$planet = Planet::where('galaxy', '00')->get();

Тогда у меня есть ниже l oop, чтобы вывести планеты, принадлежащие галактике 00 и определенной области, циклически проходя через каждую возможную область (0 - 99) и печатая счет.

$count = 0;
while($count < 100){

   echo $planet->whereRaw('CAST(region as SIGNED) = '.$count)->count();

   $count++;
}

Вещи то есть, первое целое число (где $ count равно 0) возвращает результаты, но любое последующее l oop ничего не возвращает. Если бы я установил для $ count другое значение, та же история - сначала l oop сработает, но ни один из следующих циклов не будет.

Любые идеи о том, почему это может иметь место, будут очень признательны. У меня есть echo'd $ count в l oop, чтобы дважды проверить, что он определенно печатает числа в диапазоне от 0 до 99, и это так, поэтому не уверен, почему он не возвращает результаты в запросе SQL, кроме первого.

РЕДАКТИРОВАТЬ: То, что я пытаюсь достичь, изображено ниже:

enter image description here

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

Я буду go на URL /map/00, сообщая мне, на какую галактику я смотрю, тогда будет вышеупомянутая сетка 10 x 10, каждая секция содержащий количество планет в этой области этой галактики. Каждая сетка - это div, который создается в то время как l oop.

Таким образом, фактическое значение l oop выглядит следующим образом:

$count = 0;
    while($count < 100){
       echo "<div class="inline-flex w-1/10">
       echo $planet->whereRaw('CAST(region as SIGNED) = '.$count)->count();
       echo "</div>
       $count++;
    }

Счет на месте, поэтому мы знаем в какой части сетки мы находимся, и поэтому фильтруем запрос $ astros-> whereRaw, чтобы сосредоточиться на этом регионе. Поскольку фактическая таблица является строкой, а не целым числом, мне нужно привести ее в качестве поля SIGNED для выполнения запроса where. Итак, запрос SQL, который я на самом деле ищу, ниже:

SELECT * FROM planets WHERE galaxy = 00 AND CAST(region as SIGNED) = $count

1 Ответ

0 голосов
/ 02 февраля 2020

Проблема № 1: Коллекция

Нельзя использовать whereRaw(), поскольку $planet является коллекцией, поскольку используется ->get().

$planet = Planet::where('galaxy', '00')->get(); // collection

Проблема № 2: AND , И, И, ...

Когда вы используете $planet без ->get(), вы получите множество where вместе.

$planet = Planet::where('galaxy', '00');
$count = 0;

while($count < 100){
   echo $planet->whereRaw('CAST(region as SIGNED) = '. $count)->count();

   $count++;
}

Результат

select * from `planets` where (`galaxy` = ?) and CAST(region as SIGNED) = 0

select * from `planets` where (`galaxy` = ?) and CAST(region as SIGNED) = 0 and CAST(region as SIGNED) = 1

select * from `planets` where (`galaxy` = ?) and CAST(region as SIGNED) = 0 and CAST(region as SIGNED) = 1 and CAST(region as SIGNED) = 2

select * from `planets` where (`galaxy` = ?) and CAST(region as SIGNED) = 0 and CAST(region as SIGNED) = 1 and CAST(region as SIGNED) = 2 and CAST(region as SIGNED) = 3

select * from `planets` where (`galaxy` = ?) and CAST(region as SIGNED) = 0 and CAST(region as SIGNED) = 1 and CAST(region as SIGNED) = 2 and CAST(region as SIGNED) = 3 and CAST(region as SIGNED) = 4

select * from `planets` where (`galaxy` = ?) and CAST(region as SIGNED) = 0 and CAST(region as SIGNED) = 1 and CAST(region as SIGNED) = 2 and CAST(region as SIGNED) = 3 and CAST(region as SIGNED) = 4 and CAST(region as SIGNED) = 5

....

select * from `planets` where (`galaxy` = ?) and CAST(region as SIGNED) = 0 and CAST(region as SIGNED) = 1 and CAST(region as SIGNED) = 2 and CAST(region as SIGNED) = 3 and CAST(region as SIGNED) = 4 and CAST(region as SIGNED) = 5 and CAST(region as SIGNED) = 6 and CAST(region as SIGNED) = 7 and CAST(region as SIGNED) = 8 and CAST(region as SIGNED) = 9 and CAST(region as SIGNED) = 10 and CAST(region as SIGNED) = 11 and CAST(region as SIGNED) = 12 and CAST(region as SIGNED) = 13 and CAST(region as SIGNED) = 14 and CAST(region as SIGNED) = 15 and CAST(region as SIGNED) = 16 and CAST(region as SIGNED) = 17 and CAST(region as SIGNED) = 18 and CAST(region as SIGNED) = 19 and CAST(region as SIGNED) = 20 and CAST(region as SIGNED) = 21 and CAST(region as SIGNED) = 22 and CAST(region as SIGNED) = 23 and CAST(region as SIGNED) = 24 and CAST(region as SIGNED) = 25 and CAST(region as SIGNED) = 26 and CAST(region as SIGNED) = 27 and CAST(region as SIGNED) = 28 and CAST(region as SIGNED) = 29 and CAST(region as SIGNED) = 30 and CAST(region as SIGNED) = 31 and CAST(region as SIGNED) = 32 and CAST(region as SIGNED) = 33 and CAST(region as SIGNED) = 34 and CAST(region as SIGNED) = 35 and CAST(region as SIGNED) = 36 and CAST(region as SIGNED) = 37 and CAST(region as SIGNED) = 38 and CAST(region as SIGNED) = 39 and CAST(region as SIGNED) = 40 and CAST(region as SIGNED) = 41 and CAST(region as SIGNED) = 42 and CAST(region as SIGNED) = 43 and CAST(region as SIGNED) = 44 and CAST(region as SIGNED) = 45 and CAST(region as SIGNED) = 46 and CAST(region as SIGNED) = 47 and CAST(region as SIGNED) = 48 and CAST(region as SIGNED) = 49 and CAST(region as SIGNED) = 50 and CAST(region as SIGNED) = 51 and CAST(region as SIGNED) = 52 and CAST(region as SIGNED) = 53 and CAST(region as SIGNED) = 54 and CAST(region as SIGNED) = 55 and CAST(region as SIGNED) = 56 and CAST(region as SIGNED) = 57 and CAST(region as SIGNED) = 58 and CAST(region as SIGNED) = 59 and CAST(region as SIGNED) = 60 and CAST(region as SIGNED) = 61 and CAST(region as SIGNED) = 62 and CAST(region as SIGNED) = 63 and CAST(region as SIGNED) = 64 and CAST(region as SIGNED) = 65 and CAST(region as SIGNED) = 66 and CAST(region as SIGNED) = 67 and CAST(region as SIGNED) = 68 and CAST(region as SIGNED) = 69 and CAST(region as SIGNED) = 70 and CAST(region as SIGNED) = 71 and CAST(region as SIGNED) = 72 and CAST(region as SIGNED) = 73 and CAST(region as SIGNED) = 74 and CAST(region as SIGNED) = 75 and CAST(region as SIGNED) = 76 and CAST(region as SIGNED) = 77 and CAST(region as SIGNED) = 78 and CAST(region as SIGNED) = 79 and CAST(region as SIGNED) = 80 and CAST(region as SIGNED) = 81 and CAST(region as SIGNED) = 82 and CAST(region as SIGNED) = 83 and CAST(region as SIGNED) = 84 and CAST(region as SIGNED) = 85 and CAST(region as SIGNED) = 86 and CAST(region as SIGNED) = 87 and CAST(region as SIGNED) = 88 and CAST(region as SIGNED) = 89 and CAST(region as SIGNED) = 90 and CAST(region as SIGNED) = 91 and CAST(region as SIGNED) = 92 and CAST(region as SIGNED) = 93 and CAST(region as SIGNED) = 94 and CAST(region as SIGNED) = 95 and CAST(region as SIGNED) = 96 and CAST(region as SIGNED) = 97 and CAST(region as SIGNED) = 98 and CAST(region as SIGNED) = 99

Решение # 1

$count = 0;

while ($count < 100) {
    $total = Planet::where('galaxy', '00')
        ->whereRaw('CAST(region as SIGNED) = ' . $count)
        ->count();

    echo $total;

    $count++;
}

Результат

+--------+-------+
| Region | Count |
+--------+-------+
| 00     | 1     |
| 01     | 2     |
| 02     | 1     |
| 03     | 0     |
| 04     | 0     |

....

| 99     | 0     |
+--------+-------+

Решение # 1 (лучший способ, один запрос)

$planets = Planet::select('region', \DB::raw('count(*) as total'))
    ->where('galaxy', '00')
    ->groupBy('region')
    ->pluck('total', 'region');

Результат

# region => total
array:3 [
    "00" => 1
    "01" => 2
    "02" => 1
]
...