【问题标题】:php SELECT query from five tables each with client_id in first fieldphp 从五个表中选择查询,每个表在第一个字段中都有 client_id
【发布时间】:2013-10-12 12:14:44
【问题描述】:

我有五张桌子;客户,第一节,第二节,第三节,第四节。从输入数据时开始,每个表都会在第一个字段中自动填充一个 client_id。 我想为站点上的特定客户端检索每个表(sectionone、sectiontwo、sectionthree、sectionfour)的百分比字段。我的查询工作并检索每个表的百分比字段,但不幸的是它一直为数据库中的第一个客户端返回此字段,例如 client_id 1。 如何更改下面的查询,以便获得为当前客户返回的百分比?非常感谢你的帮助。罗西

$query = "SELECT a.client_id,
       a.percent,
       b.percent,
       c. percent,
       d. percent
FROM sectionone a,
     sectiontwo b,
     sectionthree c,
     sectionfour d
WHERE a.client_id = b.client_id
  AND b.client_id = c.client_id
  AND c.client_id = d.client_id";

【问题讨论】:

  • 您应该添加一个 client_id=$actual_client_id 条件。
  • 非常感谢 Lajos Veres。我要去试试,干杯,罗西
  • 您好,Lajos Veres,您能告诉我您将如何添加您的建议吗?我尝试了变化,但不断收到错误消息。我显然不太擅长这个。我将它添加到 WHERE a.client_id = actual_client_id
  • 我发布了完整的答案。 (评论不支持代码高亮)

标签: php mysql sql


【解决方案1】:

从您的问题中很难判断您的sectiononesectiontwo 等表是否为每个客户恰好有一行。

可能的情况有这些。

  1. clientsectionone 之间的精确一对一关系等。
  2. 一对零或一关系
  3. 一对零一对多关系

从你问题的字里行间看,在我看来你相信你有第一种情况,但实际上你有第三种情况。也就是说,对于特定的客户端 ID,您可能有多个 sectionthree 行。

您想要在结果集中为每个看起来像这样的客户提供一行。

  clientid      one      two     three    four
  123           45       55      20       56

对于这样的查询来说,清楚地显示您想要的结果集很重要。但你知道的。

那么,我们开始吧。我们需要一一总结sectionX 表,因为我们必须创造一种错觉,即它们每个客户端只有一行,即使它们没有。

    SELECT client_id, AVG(percent) AS percent
      FROM sectionone
     GROUP BY client_id

相同的查询适用于所有四个sectionX 表。我们将使用其中四个汇总查询作为虚拟表,用于其余的主查询。

接下来,我们必须将这四个汇总查询加入到client 表中。我们应该使用 LEFT JOIN 命令来覆盖sectionX 表可能包含特定客户端的零行的情况。

   SELECT z.client_id, a.percent AS one,   b.percent AS two, 
                       c.percent AS three, d.percent AS four
     FROM client as z
LEFT JOIN ( 
    SELECT client_id, AVG(percent) AS percent
      FROM sectionone
     GROUP BY client_id
          ) AS a ON z.client_id = a.client_id
LEFT JOIN ( 
    SELECT client_id, AVG(percent) AS percent
      FROM sectiontwo
     GROUP BY client_id
          ) AS b ON z.client_id = b.client_id
LEFT JOIN ( 
    SELECT client_id, AVG(percent) AS percent
      FROM sectionthree
     GROUP BY client_id
          ) AS c ON z.client_id = c.client_id
LEFT JOIN ( 
    SELECT client_id, AVG(percent) AS percent
      FROM sectionfour
     GROUP BY client_id
          ) AS d ON z.client_id = d.client_id

最后,如果你只需要一个 client_id,你应该用

结束你的查询
     WHERE z.client_id = whatever

如果sectionX 表中有多个客户的行,此方法会取其值的平均值。如果您需要其他内容,例如 MAX、MIN 等,您可以在查询中使用它。

这看起来很复杂,但实际上很简单,如果您可以将五路表 LEFT JOIN 称为简单:-)。它适用于本答案开头提到的所有三种情况。

更重要的是,MySQL(和其他 SQL 系统)在优化这种查询方面做得非常好,因为它很常见。

【讨论】:

  • 你好,Ollie,我只想检索第一行的一个客户端。因此,我尝试将 a.client_id = actual_client_id 添加到我的 WHERE 语句中,但收到一条错误消息。你能说一下这个 WHERE 语句的外观吗?它是在其他条件之前还是之后?谢谢,罗西
  • Rosie,如果没有看到你的整个 WHERE 语句,我就无法判断出了什么问题。
【解决方案2】:
$query = "SELECT a.client_id,
       a.percent,
       b.percent,
       c. percent,
       d. percent
FROM sectionone a,
     sectiontwo b,
     sectionthree c,
     sectionfour d
WHERE a.client_id = b.client_id
  AND b.client_id = c.client_id
  AND c.client_id = d.client_id
  AND a.client_id = 1
";

【讨论】:

  • 感谢您告诉我在哪里添加条件,即 a.client_id = 1。但我的问题是,即使客户端 x 位于网页上,它也已经返回第一个客户端。我希望它返回网页上的实际客户。 a.client_id = '' 你认为会这样做吗?我可以用什么代替(1)?欣赏,罗西
  • 您应该从某个地方知道哪个用户实际上在您的页面上。 “通用”解决方案是登录用户,将用户 ID 保存到会话中,并在这样的查询中使用保存的用户 ID。这个主题有很好的教程。
【解决方案3】:

感谢您的帮助,我现在得到了有效的答案:

$query = "SELECT a.client_id,
   a.percent,
   b.percent,
   c. percent,
   d. percent
FROM sectionone a,
 sectiontwo b,
 sectionthree c,
 sectionfour d
WHERE a.client_id = b.client_id
AND b.client_id = c.client_id
AND c.client_id = d.client_id          

添加了额外的代码

ORDER BY client_id DESC";

这会为当前用户提供结果。很高兴,罗西

【讨论】:

    猜你喜欢
    • 2011-07-09
    • 2013-07-16
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-04-07
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多