2012-10-19 77 views
1

这是一个包含多个部分的问题。我的数据库看起来是这样的:带外键表的PHP嵌套循环

USERS 
-id 
-fname 
-lname 

COMPANIES 
-id 
-name 
-type 

PRODUCTS 
-id 
-product 
-restaurant (foreign key to companies id) 
-vendor (foreign key to companies id) 
-user (foreign key to users id) 
-transaction_date 
  1. 这是一个很好的方式来建立数据库?我正在考虑为餐厅和供应商提供单独的表格,但希望他们使用相同的登录页面,而不必担心UNION查询,我只是按类型选择它们。他们在登录时看到不同的信息,所以我有一个if语句,表示如果type = r,则显示这个else表明。最好的办法?

当我想在登录时显示信息时出现第二个问题。说一个供应商登录,他们将看到一个与其供应商ID匹配的所有记录的列表。但是,由于嵌套循环,我看到的记录太多。例如,表看起来像这样:

Date--Product--Restaurant--User 

我使用此查询:

$sql = mysql_query("SELECT products.*, companies.name, CONCAT_WS(' ', users.fname, users.lname) AS fullname FROM products INNER JOIN companies ON products.vendor = companies.id INNER JOIN users ON products.user = users.id WHERE company='$id' AND companies.type='$type'") or die(mysql_error()); 

$num=mysql_num_rows($sql); 

$sql1 = mysql_query("SELECT products.restaurant, companies.name AS cname FROM products INNER JOIN companies ON products.restaurant = companies.id") or die(mysql_error()); 

$num1=mysql_num_rows($sql1); 

$i = 0; 
while ($i < $num) { 
    $j = 0; 
    while ($j < $num) { 
$d = mysql_result($sql,$i,"transaction_date"); 
$p = mysql_result($sql,$i,"product"); 
$r = mysql_result($sql1,$j,"cname"); 
$u = mysql_result($sql,$i,"fullname"); 

<td><?php echo $d; ?></td> 
<td><?php echo $p; ?></td> 
<td><?php echo $r; ?></td> 
<td><?php echo $u; ?></td> 

$j++; } 
$i++; } 

$id$type是在登录会话创建的值。目前有4个示例记录在表格中。而不是仅显示4,它显示16,因为$num$num1的值均为4,并且$num正在循环$num1四次。

  1. 我该如何解决这个问题,只显示4条记录?

谢谢你的帮助。如果您需要对任何部分进行澄清,请告知我们。

+0

确实每个产品都有且只有一个用户?如果是的话,你的模式看起来很好如果不是,您需要制作一个包含product_id,user_id和交易日期的product_users表。 – sgroves

+0

是的每个产品只有一个用户。实际上,我应该将产品表重命名为交易,因为基本上只有一种产品。 – robk27

回答

1

您的数据库设置可能需要一点反思。

我认为这是因为您需要知道每个用户在哪个公司,并且您不能在产品表中拥有此内容。 (假设一个用户有一个公司,一个公司有很多用户),我会考虑将外键添加到用户表中。我还提出了一些其他建议,像下面:

用户 - ID - COMPANY_ID - FIRST_NAME - 姓氏

公司 - ID - 姓名 - company_type_id

company_types - ID - 型

产品 - ID - PRODUCT_NAME - COMPANY_ID

交易 - ID - user_ID的 - PRODUCT_ID - TRANSACTION_DATE

they will see a list of all the records that match their vendor

现在,您将诺蒂奇e我从上表中删除了供应商ID - 这是因为供应商ID与公司ID相同。目前有两个独立的关系ID对同一件事(纠正我,如果我错了)

上述变化,我们可以很容易地列出这些记录

因此,没有点,像这样:

<?php 

    $db = new PDO(/**Connection info here**/); 
    $stmt = $db->prepare(" 
    SELECT 
     a.id AS product_id, 
     a.product_name 
    FROM 
     products AS a 
    INNER JOIN 
     companies AS b ON b.id = a.company_id 
    INNER JOIN 
     company_types AS c ON c.id = b.type_id 
    WHERE 
     b.id = :company AND c.id = :companyType 
    "); 
    $stmt->bindParam(":company", $usersCompanyIdHere, PDO::PARAM_INT); 
    $stmt->bindParam(":companyType", $usersCompanyTypeHere, PDO::PARAM_INT); 

    $data = $stmt->execute(); 

    while ($row = $data->fetch()) { 
    /** List of all the products for given company id**/ 
    } 

?> 

我有改变你的代码使用PDO,我不想在这里超载你的信息,但我不能强调足够的使用PDO本地mysql_*函数的好处 - 做一个谷歌搜索,我可以看到很多有用的前10名成绩中的相关信息。

+0

谢谢你的回复。您提供了非常详细的答案,但我可能没有正确解释设计。有客户,供应商和餐馆。基本上只有一种产品,所以我应该将'Products'表重命名为'Transactions'。 “Transactions”表中的每条记录都将包含日期,用户,餐馆和供应商。当供应商登录时,他们只会看到包含它们的记录,向他们显示日期,用户,餐厅。当一家餐厅登录时,他们将看到包含他们的记录,向他们显示日期,用户,供应商。 – robk27

+0

我把供应商和餐馆放在'公司'的同一张桌子下,因为我不想做两个表的UNION查询。我可以查询一张表格向我显示我要求的数据设置方式吗?如果是这样如何?谢谢。 – robk27

+0

我看着PDO,并将实现这一点。你知道我的数据库设计是否有效吗?或者我应该改变它,使循环可以工作? – robk27