требуется компиляция массива из справки mysql - PullRequest
1 голос
/ 23 октября 2008

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

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 сортов.

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

Ответы [ 6 ]

2 голосов
/ 23 октября 2008

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

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 , посмотрите на нее.

1 голос
/ 23 октября 2008

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

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

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

0 голосов
/ 24 октября 2008
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);
0 голосов
/ 23 октября 2008
$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
0 голосов
/ 23 октября 2008

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

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

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);
0 голосов
/ 23 октября 2008
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

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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...