Требуется компиляция массива из mysql

Это меня беспокоит, я не могу понять это. Я воспользуюсь аналогией с продуктами питания, чтобы попытаться упростить мою задачу.

1000 представителей общественности попросили выбрать по каждой из 13 категорий обуви для ног. Эти выборы затем сохранялись в базе данных mysql под своим именем.

e.g.    billy   mary   etc.   etc.

milk....semi. .skimmed...

bread...white...brown....

cheese..edam.....edam....

fruit...apple...orange...

veg....potato...sprout...

meat....beef.....beef....

sweet..bonbons..liquorice..

fish...trout....salmon...

crisp....s&v....plain....

biscuit..hovis..rich tea..

wine.....red.....red.....

beer....stella..carlsburg..

carb....coke.....pepsi....

Затем одного из этих 1000 попросили выбрать от нуля до 13 вариантов с помощью флажков.

Путем поиска в базе данных, сколько других выбрали те же сорта?

Отобразите в таблице все их названия и то, что они выбрали для всех 13 разновидностей.

Имеет ли это смысл? Я надеюсь на это, потому что это сводит меня с ума.

Может быть, еще можно показать, как вы планируете хранить эту информацию в базе данных? Как бы выглядели таблицы?

Hallgrim 23.10.2008 01:32

Привет, Халлгрим. Конечно. Таблица содержит названия продуктов и участников в виде текстовых полей. То, что они выбрали из каждого поля, записывается напротив их имен. Их имена уникальны и увеличиваются с помощью идентификатора пользователя. Есть только одна таблица.

Nick Berardi 23.10.2008 02:33

Значит, в таблице 13 столбцов с продуктами питания?

Darryl Hein 23.10.2008 02:36

Привет, Дэррил. Да и одно имя и один идентификатор пользователя.

Eggs McLaren 23.10.2008 02:40

Я думаю, было бы намного проще иметь 2 таблицы, одну с пользователем, а другую с отношениями между продуктами и идентификатором user_id.

Darryl Hein 23.10.2008 02:51

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

nickf 23.10.2008 03:56
Стоит ли изучать PHP в 2026-2027 годах?
Стоит ли изучать PHP в 2026-2027 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Symfony Station Communiqué - 7 июля 2023 г
Symfony Station Communiqué - 7 июля 2023 г
Это коммюнике первоначально появилось на Symfony Station .
Оживление вашего приложения Laravel: Понимание режима обслуживания
Оживление вашего приложения Laravel: Понимание режима обслуживания
Здравствуйте, разработчики! В сегодняшней статье мы рассмотрим важный аспект управления приложениями, который часто упускается из виду в суете...
Установка и настройка Nginx и PHP на Ubuntu-сервере
Установка и настройка Nginx и PHP на Ubuntu-сервере
В этот раз я сделаю руководство по установке и настройке nginx и php на Ubuntu OS.
Коллекции в Laravel более простым способом
Коллекции в Laravel более простым способом
Привет, читатели, сегодня мы узнаем о коллекциях. В Laravel коллекции - это способ манипулировать массивами и играть с массивами данных. Благодаря...
Как установить PHP на Mac
Как установить PHP на Mac
PHP - это популярный язык программирования, который используется для разработки веб-приложений. Если вы используете Mac и хотите разрабатывать...
1
6
216
6

Ответы 6

частичный ответ:

  • составить линейный набор выборок путем сортировки и объединения
  • сравнение становится простым предложением WHERE

поэтому сначала вы должны выполнить расчет, буквально поместив строки в какое-нибудь поле, например «молоко | полу | обезжиренное».

Предполагая, что у вас простой макет, у вас будет что-то вроде этого (я ограничусь тремя категориями):

PersonId  What_Milk  What_Bread  What_Cheese
       1  Semi       Wheat       Swiss
       2  Skimmed    Rolls       French
       3  Soy        Brown       Smelly
       4  Low Fat    Wheat       Swiss

Если я правильно понял, ваша проблема в следующем:

Когда человека 4 просят выбрать 0 .. 3 из его продуктов питания, он может установить флажки «Хлеб» и «Сыр», что означает, что запрос должен дать человека 1 в качестве совпадения. Верно?

SELECT
  PersonId,
  What_Milk,
  What_Bread,
  What_Cheese
FROM
  FoodPreference
WHERE
  PersonId != ?
  AND What_Milk   = IFNULL(NULLIF(?, ''), What_Milk)
  AND What_Bread  = IFNULL(NULLIF(?, ''), What_Bread)
  AND What_Cheese = IFNULL(NULLIF(?, ''), What_Cheese)

Значения вашего флажка позже переместятся туда, где находятся заполнители вопросительного знака. (Я заменил конструкции CASE WHEN, которые использовались здесь, на IFNULL / NULLIF, которые имеют тот же эффект, но более удобны для подготовленных операторов PHP.)

Если флажок не установлен (таким образом, фиксируя значение чего-либо), соответствующий столбец сравнивается с самим собой. Это означает, что его значение не влияет на результат. Если другие столбцы совпадают, будет выбрана строка.

Это также означает, что если пользователем установлены флажки нуль, будут возвращены строки все. Чем больше продуктов выберет человек, тем точнее совпадение будет.

В PHP я бы рекомендовал вам использовать mysqli_prepare() для создания подготовленного оператора из строки запроса и mysqli_stmt_bind_param() для привязки фактических значений к заполнителям вопросительного знака. Это намного безопаснее, чем строить строку SQL напрямую. В документации PHP есть много информации о mysqli., взгляните на него.

Привет Томалак. Да, если человеку 4 в вашем примере было предложено выбрать, и он установил флажки «Хлеб» и «Сыр», тогда все, кто выбрал то же, что и она, для этих двух продуктов питания должны быть отклонены. Поскольку нам нужно отображать все, что они выбрали, SELECT должен быть * not PersonId? И да, чем меньше .....

Nick Berardi 23.10.2008 02:48

..... флажки отмечены тем больше результатов. Установка флажков сужает поиск. Я не знаю этого СЛУЧАЯ КОГДА термин? Сейчас поищу.

Eggs McLaren 23.10.2008 02:50

Да, выберите те столбцы, которые вам нужны, это был пример. Избегайте общего «SELECT *» в производственном коде, он менее эффективен.

Tomalak 23.10.2008 02:56

Я поддерживаю предложение Томалака использовать подготовленные параметры оператора вместо интерполяции переменных PHP в выражения SQL.

Bill Karwin 23.10.2008 03:51

В ПОРЯДКЕ. Итак, если значение флажка идет туда, где у вас есть? что делают пустые кавычки?

Nick Berardi 23.10.2008 04:26

Пустые кавычки - это небольшая хитрость, заставляющая NULLIF производить NULL, если вы не указываете значение флажка, поэтому IFNULL может заменить его исходным значением столбца. Прочтите также документацию по mysql и попробуйте сами выражения, чтобы понять их.

Tomalak 23.10.2008 10:47
SELECT  
    PersonId,  
    milk,  
    bread,  
    cheese
FROM  FoodPreference
WHERE  PersonId != :chosen_person_id  
    AND $milk= CASE WHEN :isset($_POST["milk"]))> '' THEN :isset($_POST["milk"]))   ELSE milk END  
    AND $bread= CASE WHEN :isset($_POST["bread"]))> '' THEN :isset($_POST["bread"]))  ELSE bread END  
    AND $cheese= CASE WHEN :isset($_POST["cheese"]))> '' THEN :isset($_POST["cheese"])) ELSE cheese END

Я на правильном пути?

Попробуйте использовать кнопку формата кода, чтобы сделать отступ в коде и сделать его более читабельным. Я думаю, вы приближаетесь ... как-то. Я немного обновлю свой пример, поскольку знаю, что вы используете PHP.

Tomalak 23.10.2008 03:24

Хорошо, я отправил один ответ, но Томалак совершенно справедливо указал на логический недостаток. Попробую еще раз:

Альтернативой перечислению категорий в виде тринадцати столбцов является перечисление их в виде тринадцати строк в таблице, как показано ниже:

CREATE TABLE FoodPreference (
  PersonID   INT NOT NULL REFERENCES People,
  FoodCat    VARCHAR(10) NOT NULL REFERENCES FoodCategories,
  FoodChoice VARCHAR(10) NOT NULL,
  PRIMARY KEY (PersonID, FoodCat)
);
INSERT INTO FoodPreference VALUES
  (123, 'bread', 'white'),
  (123, 'milk', 'skim'),
  (123, 'cheese', 'edam'), ...
  (321, 'bread', 'brown'),
  (321, 'milk', 'whole'),
  (321, 'cheese', 'edam'), ...

Затем вы можете использовать следующий запрос, сопоставляя любую строку от выбранного человека (p1) строке с тем же выбором еды от другого человека (p2) и оттуда для всех других вариантов выбора этого человека (p3):

SELECT DISTINCT p3.*
FROM FoodPreference AS p1
  JOIN FoodPreference AS p2 
    ON (p1.FoodCat = p2.FoodCat AND p1.FoodChoice = p2.FoodChoice 
      AND p1.PersonID != p2.PersonID)
  JOIN FoodPreference AS p3 
    ON (p2.PersonID = p3.PersonID AND p2.FoodCat != p3.FoodCat)
WHERE p1.PersonID = {(int)$chosen_person_id}
  AND p1.FoodCat IN ('milk', 'bread', 'cheese');

Список «молоко», «хлеб», «сыр» в предложении WHERE - это то, что вам нужно встроить в свой PHP-код на основе переменной $_POST в вашем приложении. Если флажок установлен, включите эту категорию продуктов питания в список.

<?php
$food_cat_array = array("'none'");
$legal_food_cats = array('milk'=>1, 'bread'=>1, 'cheese'=>1, ...);
foreach (array_intersect_key($_POST, $legal_food_cats) as $key => $checked) {
  if ($checked) {
    $food_cat_array[] = "'$key'"; 
  }
}
$in_predicate = join(',', $food_cat_array);

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

Eggs McLaren 23.10.2008 05:48

И теперь я использую свои фактические значения. Не уверен, правильно ли я сравниваю. Смотрите мой новый код ниже. Получение некоторых ошибок mysql. Недействительный ресурс результата и т. д.

Chris Jester-Young 23.10.2008 05:49
$sql = mysql_query("        
    SELECT  
    *
    FROM  ".$prefix."_users
    WHERE  username !='$username'  
    AND req_country   = IFNULL(NULLIF($bcountry, ''), req_country)  
    AND req_region  = IFNULL(NULLIF($bregion, ''), req_region)  
    AND req_type = IFNULL(NULLIF($btype, ''), req_type)
    AND req_beds = IFNULL(NULLIF($bbeds, ''), req_beds)
    AND req_value = IFNULL(NULLIF($bvalue, ''), req_value)
    AND country   = IFNULL(NULLIF($scountry, ''), country)  
    AND region  = IFNULL(NULLIF($sregion, ''), region)  
    AND type = IFNULL(NULLIF($stype, ''), type)
    AND beds = IFNULL(NULLIF($sbeds, ''), beds)
    AND value = IFNULL(NULLIF($svalue, ''), value)
    AND pool = IFNULL(NULLIF($spool, ''), 'Yes')
    AND garage = IFNULL(NULLIF($sgarage, ''), >0) 
            AND disabled = IFNULL(NULLIF($sdisabled, ''), 'Yes')");
$num = mysql_num_rows($sql);
echo "Total matches ($num): <br><br>";
        while($row = mysql_fetch_array($sql)){...etc

Имейте в виду, что AND имеет более высокий приоритет, чем OR. Вероятно, вам стоит добавить в скобки девять терминов гаража.

Bill Karwin 23.10.2008 06:20

это должно быть «req_country = IFNULL (NULLIF ('$ bcountry', ''), req_country)» и так далее. Также, как сказал Билл, все условия «ИЛИ» должны быть заключены в один набор заключающих скобок.

Tomalak 23.10.2008 10:52

Спасибо. Я редактировал код, как он теперь выглядит? Пул и Отключено хранятся в базе данных как Да и Нет. Я хочу, чтобы эти строки были выбраны только в том случае, если флажок установлен и установлено значение Да; так я сделал это правильно или это должно быть нет? Также могу я просто сказать> 0 для гаража?

Eggs McLaren 23.10.2008 14:57

Нет, здесь нельзя сказать> 0, это недопустимый синтаксис. Попробуйте заменить термин гараж на: CASE IFNULL ($ sgarage, '') WHEN '' THEN garage IN (0,1,2,3,4,5,6,7,8,9) ELSE garage = $ sgarage END

Bill Karwin 23.10.2008 22:49

@Nigel: Я думаю, вам нужно больше времени уделять изучению SQL (и PHP). Без обид, но ты видел довольно ... ну ... не обученный этому. Мы показали вам, что делать, я думаю, вам просто нужно больше времени, чтобы соединить биты.

Tomalak 24.10.2008 01:12

хе-хе ... Ты так прав, Томалак. Я не занимался программированием 25 лет, когда я мог делать что угодно в Sinclair ZX81 basic !! Тем не менее, я начинаю это понимать. Я понял эту проблему, спасибо за вашу помощь и Билл, ура. Взгляни на мой код. Работает отлично, ребята, недоработки?

Chris Jester-Young 24.10.2008 03:18
case "display_results":

if ($bcountry = !isset($_POST["bcountry"])){
      $bcountry = "No";
      }else {
      $bcountry = "Yes";
      }
if ($bregion = !isset($_POST["bregion"])){
      $bregion = "No";
      }else {
      $bregion = "Yes";
      }
if ($btype = !isset($_POST["btype"])){
      $btype = "No";
      }else {
      $btype = "Yes";
      }
if ($bbeds = !isset($_POST["bbeds"])){
      $bbeds = "No";
      }else {
      $bbeds = "Yes";
      }
if ($bvalue = !isset($_POST["bvalue"])){
      $bvalue = "No";
      }else {
      $bvalue = "Yes";
      }
if ($scountry = !isset($_POST["scountry"])){
      $scountry = "No";
      }else {
      $scountry = "Yes";
      }
if ($sregion = !isset($_POST["sregion"])){
      $sregion = "No";
      }else {
      $sregion = "Yes";
      }
if ($stype = !isset($_POST["stype"])){
      $stype = "No";
      }else {
      $stype = "Yes";
      }
if ($sbeds = !isset($_POST["sbeds"])){
      $sbeds = "No";
      }else {
      $sbeds = "Yes";
      }
if ($svalue = !isset($_POST["svalue"])){
      $svalue = "No";
      }else {
      $svalue = "Yes";
      }
if ($spool = !isset($_POST["spool"])){
      $spool = "No";
      }else {
      $spool = "Yes";
      }
if ($sgarage = !isset($_POST["sgarage"])){
      $sgarage = "No";
      }else {
      $sgarage = "Yes";
      }
if ($sdisabled = !isset($_POST["sdisabled"])){
      $sdisabled = "No";
      }else {
      $sdisabled = "Yes";
      }

     $result = mysql_query("SELECT * FROM  ".$prefix."_users WHERE  username!='$username' 
AND (('$bcountry'='Yes' AND req_country= '$country') OR ('$bcountry'='No')) 
AND (('$bregion'='Yes' AND req_region= '$region') OR ('$bregion'='No'))
AND (('$btype'='Yes' AND req_type= '$type') OR ('$btype'='No'))
AND (('$bbeds'='Yes' AND req_beds= '$beds') OR ('$bbeds'='No'))
AND (('$bvalue'='Yes' AND req_value= '$value') OR ('$bvalue'='No'))
AND (('$scountry'='Yes' AND country= '$req_country') OR ('$scountry'='No'))
AND (('$sregion'='Yes' AND region= '$req_region') OR ('$sregion'='No'))
AND (('$stype'='Yes' AND type= '$req_type') OR ('$stype'='No'))
AND (('$sbeds'='Yes' AND beds= '$req_beds') OR ('$sbeds'='No'))
AND (('$svalue'='Yes' AND value= '$req_value') OR ('$svalue'='No'))
AND (('$spool'='Yes' AND pool= 'Yes') OR ('$spool'='No'))
AND (('$sgarage'='Yes' AND garage>=1 ) OR ('$sgarage'='No'))
AND (('$sdisabled'='Yes' AND disabled= 'Yes') OR ('$sdisabled'='No'))
")or die("MySQL ERROR: ".mysql_error());
$number = mysql_num_rows($result);

Я бы хотел, чтобы флажки оставались отмеченными после отображения результатов поиска (чтобы люди могли видеть, что они выбрали). Я пробовал добавить $ ticked1, $ ticked2 и т. д. К параметрам флажка, а затем if ($ bcountry == 'Yes') {$ ticked1 = 'Checked'} и т. д., Но это не работает. Любая помощь?

Eggs McLaren 24.10.2008 03:34

Другие вопросы по теме