【问题标题】:SQL statement to display in group of certain columnSQL 语句在某列的组中显示
【发布时间】:2014-07-23 07:59:07
【问题描述】:

我目前正在从事基于网络创建调度系统的项目。我想从数据库中获取数据,并将其显示在表格中(计划格式)。

在数据库中,我有 2 个表

时间表
身份证日期日期
1 22/09/2014 星期一
2 2014 年 9 月 23 日星期二
块
block_id schedule_id 工人班次
1 1 艾哈迈德 1
2 1 阿卜杜勒 1
3 1 法里斯 2
4 2 伊克巴尔 2

日程表的每一天都有几个块,schedule_id(块中)是指它应该是哪一天。列移(在块中)将块定义为早上(shift=1)和晚上(shift=2),

我想展示这样的东西

约会 一天 早上 晚上 22/09/2014 星期一 Ahmad Faris 阿卜杜勒 23/09/2014 星期二 伊克巴尔

我尝试过创建类似的sql语句

选择 schedule.date、schedule.day、block.worker 从时间表 左连接块 ON schedule.id = block.schedule_id

但表格的格式不合适

约会 一天 早上 晚上 22/09/2014 星期一 艾哈迈德 22/09/2014 星期一 阿卜杜勒 22/09/2014 星期一 法里斯 23/09/2014 星期二 伊克巴尔

我知道我的陈述中遗漏了一些东西,以及我如何做到这一点。

感谢您的帮助。

【问题讨论】:

    标签: php mysql sql database phpmyadmin


    【解决方案1】:

    最初,这是我想出的:

    SELECT s.date, s.day, COALESCE(GROUP_CONCAT(bm.worker SEPARATOR ' '),'') as Morning,COALESCE(GROUP_CONCAT(be.worker SEPARATOR ' '),'') as Evening
    FROM schedule s LEFT JOIN 
    block bm ON s.id = bm.schedule_id AND bm.shift=1 LEFT JOIN 
    block be ON s.id = be.schedule_id AND be.shift=2
    GROUP BY s.date,s.day
    

    结果:

    DATE        DAY       MORNING       EVENING
    22/09/2014  Monday    Ahmad Abdul   Faris Faris
    23/09/2014  Tuesday                 Iqbal
    

    结果为@​​987654321@。

    如您所见,Evening 字段包含两次 Faris。所以我使用了两个查询并加入了这些结果。像这样:

    SELECT T1.date,T1.day,COALESCE(T1.Morning,'') as Morning,COALESCE(T2.Evening,'') as Evening FROM
        (SELECT s.date, s.day, GROUP_CONCAT(bm.worker SEPARATOR ' ') as Morning
         FROM schedule s LEFT JOIN 
         block bm ON s.id = bm.schedule_id AND bm.shift=1
         GROUP BY s.date,s.day) T1
      JOIN
        (SELECT s.date, s.day,GROUP_CONCAT(be.worker SEPARATOR ' ') as Evening
         FROM schedule s LEFT JOIN 
         block be ON s.id = be.schedule_id AND be.shift=2
         GROUP BY s.date,s.day) T2 
      ON T1.Date=T2.Date AND T1.Day=T2.Day
    

    结果:

    DATE        DAY      MORNING        EVENING
    22/09/2014  Monday   Ahmad Abdul    Faris
    23/09/2014  Tuesday                 Iqbal
    

    SQL Fiddle 中查看结果。

    说明:

    我们分别选择 Morning 和 Evening,然后将这两个表与日期和日期连接起来。最后从连接的查询中获取结果。

    GROUP_CONCAT 用于对具有相同日期和日期的字段进行分组。我们可以使用SEPARATOR ' ' 作为空间分隔符。如果你删除SEPARATOR ' ',你会得到用逗号(,)分隔的结果。

    COALESCE 用于将空值替换为空字符串('')。

    【讨论】:

    • @iqbalplague:你可以在小提琴示例中看到结果。
    • 我如何将它显示在不同的行中,是否需要任何标签? (如
    • @iqbalplague:在不同的行?其他字段为空?这不是 SQL 的工作方式。在这种情况下,我更喜欢逗号分隔值。
    • 其实我会使用worker_id而不是worker name,并将它们加入到其他worker表中。
    • 好的,我会尽力寻找你的答案。感谢您的指导:)
    【解决方案2】:

    您可以通过使用单独的班次过滤器两次加入您的块表来获得所需的结果

    SELECT 
      s.date,
      s.day,
      b.worker Morning,
      bb.worker Evening 
    FROM
      SCHEDULE s 
      LEFT JOIN block b 
        ON s.id = b.schedule_id 
        AND b.`shift` = 1 
      LEFT JOIN block bb 
        ON s.id = bb.schedule_id 
        AND bb.`shift` = 2  
      ORDER BY s.date
    

    Demo

    关于您显示的格式,可以通过使用用户定义的变量和重复数据显示为空的查询来实现,但是此查询将变得如此丑陋,并且无法保证优化。最好在您的应用程序级代码,即 php

    从 cmets 编辑

    在 php 中,只需使用您的逻辑每组仅显示一次日期,从您的查询中获取结果

    $results =fetchfromquery(query);
    $currentParent = false;
    echo '<table>';
    echo '<tr>
            <td>Date</td>
            <td>Day</td>
            <td>Morning</td>
            <td>Evening</td>
        </tr>';
    foreach ($results as $r) {
        echo '<tr>';
        if ($currentParent != $r['date']) {
            echo '<td>' . $r['date'] . '</td>';
            $currentParent = $r['date'];
        }else{
            echo '<td>&nbsp;/td>';
        }
        echo '<td>' . $r['day'] . '</td>';
        echo '<td>' . $r['Morning'] . '</td>';
        echo '<td>' . $r['Evening'] . '</td>';
        echo '</tr>';
    }
    echo '</table>';
    

    上面将以表格格式输出数据,如下所示

    <table>
        <tr><td>Date</td>       <td>Day</td>    <td>Morning</td>   <td>Evening</td></tr>
        <tr><td>22/09/2014</td> <td>Monday</td>  <td>Abdul</td>    <td>Faris</td></tr>
        <tr><td>          </td> <td>Monday</td>  <td>Ahmad</td>    <td>Faris</td></tr>
        <tr><td>23/09/2014</td> <td>Tuesday</td>  <td>      </td>    <td>Iqbal</td></tr>
    </table>
    

    【讨论】:

    • 是否需要像“GROUP by”这样的语句,因为我想在包含多个块的一行中只显示一个日期和日期..(就像我想要的格式)
    • @iqbalplague 看到我回答的最后一部分,这就是我所说的重复数据,您只需要按日期排序,并在应用程序级代码循环通过记录和循环检查或重复数据并显示只有一次
    • @iqbalplague 看我对这个问题的回答Combining Three tables into correct view format我是如何完成循环检查重复数据的,与上述查询相同的逻辑,另一个答案php category, sub category tree
    • 我明白了,所以重复的功能是在应用程序级别完成的。感谢您的指导,我会努力的:)
    • 嗨,我一直在尝试使用您的答案,但似乎问题不大。我一直在我的应用程序级别使用循环代码,但界面不合适。可以请教一下吗?
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-01-18
    • 1970-01-01
    • 2012-09-09
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多