选择所需的结果SQL.使用连接或左连接的多个表

Joe*_*ito 2 php mysql

我正在尝试提出一个Web应用程序,有点像逐步程序性的应用程序.我无法真正描述它并且不知道如何调用它,但它是一个应用程序,它提供了有关如何实现某些内容(如作业应用程序)的逐步说明.

"帮助用户了解如何做事的应用程序."

所以我设置了一些GUI,现在我面临问题的核心:数据库设置.

在我设计的GUI中,我决定它是这样的:

图1.0

传说:

  • 绿色与支票 - 完成
  • 橙色 - 用户当前正在执行该步骤
  • 灰色 - 他还没有开始任何子步骤.

正如图片所暗示的,我有3个顶层程序,以及其他一些儿童的程序 下的每个过程.在这张照片中缺少的一件事是,顶级程序也属于某一类别.

我想要实现的是跟踪用户的活动.这是交易:

  1. 您没必要完成第一个顶级程序以继续下一个程序,您可以跳过并返回 - >没有问题.
  2. 在完成所有子程序之后,顶级程序为该特定用户标记1,意味着它已完成.
  3. 对于该类别也是如此,当该类别下的所有顶层程序完成时,该特定用户的类别标记1,意味着他/她完成了该类别.

我打算像这样设置我的数据库:

-tbl_users-

 id    |    username    |    password    |
 -----------------------------------------
   1   |    some_user   |  adf8jkdfndsa  |
...
Run Code Online (Sandbox Code Playgroud)

tbl_step_cat

 id    |      cat_name      |
 ---------------------------
   1   |    some_category   |
...
Run Code Online (Sandbox Code Playgroud)

tbl_steps

 id    |      step_shortdesc     |    step_longdesc      |  cat_id 
 -------------------------------------------------------------------
   1   |      some step one      |  do the following...  |     1
 -------------------------------------------------------------------
   2   |      some step two      |  do the following...  |     1
 -------------------------------------------------------------------
   3   |      some step three    |  do the following...  |     2
...
Run Code Online (Sandbox Code Playgroud)

tbl_substeps

 id    |     substep_shortdesc   |    substep_longdesc   |  step_id 
 -------------------------------------------------------------------
   1   |    some substep one     |  do the following...  |     1
 -------------------------------------------------------------------
   2   |    some substep two     |  do the following...  |     1
 -------------------------------------------------------------------
   3   |    some substep three   |  do the following...  |     1
 -------------------------------------------------------------------
   4   |    some substep a       |  do the following...  |     2
 -------------------------------------------------------------------
   5   |    some substep b       |  do the following...  |     2
 -------------------------------------------------------------------
   6   |    some substep 1       |  do the following...  |     3
...
Run Code Online (Sandbox Code Playgroud)

然后是用户和步骤之间的关系表

tbl_user_stepcat

 id    |     user_id   |    stepcat_id   |  datetime 
 -------------------------------------------------------------------
   1   |      1        |       1         |  sometime
 -------------------------------------------------------------------
   2   |      1        |       2         |  sometime
 -------------------------------------------------------------------
Run Code Online (Sandbox Code Playgroud)

tbl_user_step

 id    |     user_id   |     step_id     |  datetime 
 -------------------------------------------------------------------
   1   |      1        |       1         |  sometime
 -------------------------------------------------------------------
   2   |      1        |       2         |  sometime
 -------------------------------------------------------------------
Run Code Online (Sandbox Code Playgroud)

tbl_user_substep

 id    |     user_id   |    substep_id   |  datetime 
 -------------------------------------------------------------------
   1   |      1        |       1         |  sometime
 -------------------------------------------------------------------
   2   |      1        |       2         |  sometime
 -------------------------------------------------------------------
Run Code Online (Sandbox Code Playgroud)

如果这有点长,我很抱歉,这只是因为代码.

现在我的问题是如何返回我想要的结果.如您所见,当用户登录到应用程序时,我希望他/她能够立即查看这些信息.

我从未尝试过这一刻,因为我的大脑刚关闭而且没有焦点,这是我迄今为止最好的时间.

如果我要编写这个应用程序的SQL代码,我会做多个连接.

我想首先选择所有类别并将其输出给用户.

SELECT * FROM tbl_step_cat
Run Code Online (Sandbox Code Playgroud)

这将给我所有的类别,我接下来要做的是找出完成的步骤,以便我可以做'样式'

我可能会这样做

SELECT cat_name FROM tbl_step_cat JOIN
tbl_user_stepcat ON tbl_user_stepcat.stepcat_id = tbl_step_cat.id
...
Run Code Online (Sandbox Code Playgroud)

我失去了焦点,现在无法思考.我该怎么做:

  1. 输出所有猫/步/子步
  2. 在关系表中获取具有条目的人,这意味着它已经完成
  3. 哪里 user = session['user']

非常感谢,我只需要指导.

小智 5

好的,如果您只是指定JOIN,那将是一个内部联接,因此将排除用户尚未完成每​​个步骤和子步骤的结果.因此,为了确保您可以获得每个连接的结果,我将使其成为LEFT JOIN.这可以使用null结果加入它,这很好,因为您可以测试子类别字段是否为null,以便填充表单上的刻度部分.

我一直认为将数据库逻辑拆分成单独的查询是没有坏处的,而不是试图编写一个将所有内容连接到一切的巨型查询,这可能是过多的.

我想我会对每个类别进行单独查询,即:

(伪)

SELECT * FROM CATEGORIES 
foreach (category) {
    SELECT * FROM SUBCATEGORIES WHERE CATEGORY = CATEGORYID
    foreach (SUBCATEGORY) {
        SELECT * FROM SUBSUBCATEGORIES WHERE SUBCATEGORY = SUBCATEGORYID
    }
}
Run Code Online (Sandbox Code Playgroud)

并在每个点查询用户表,以查看用户是否在遍历列表时完成了每个步骤,并使用该循环填充您的刻度.

它可能不如单个巨型连接那么优雅,但如果这不是你的事情,我认为简化查询逻辑以帮助你的理解没有任何伤害.