需要帮助了解mysql LEFT JOINS和DataTables

时间:2011-11-24 10:56:52

标签: php mysql join database-table

我试图了解MySQL。我已经从在线信息中学到了很多东西,但是我很少理解JOINS如何工作以及如何融入DataTables代码。

我有这个表结构:

I have this table structure:

这个MySql声明:

SELECT leads.lead_id, leads.date_time, clients.username, courses.course_type, courses.location_name, CONCAT(first_name,' ',surname)
FROM courses
LEFT JOIN leads ON leads.lead_get_course_id = courses.course_id 
LEFT JOIN clients ON clients.client_id = courses.course_get_client_id
WHERE leads.checked_by_admin = 'No'

当我在Dreamweaver中测试它时一切正常但是,当我尝试将其应用于DataTables代码时,我在'字段列表'中得到未知列'leads.lead_id'

以下是我的DataTables代码:

<?php
/*
 * Script:    DataTables server-side script for PHP and MySQL
 * Copyright: 2010 - Allan Jardine
 * License:   GPL v2 or BSD (3-point)
 */

/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
 * Easy set variables
 */

/* Array of database columns which should be read and sent back to DataTables. Use a space where
 * you want to insert a non-database field (for example a counter or static image)
 */
$aColumns = array(     
"leads.lead_id", 
"leads.date_time", 
"clients.username", 
"courses.course_type", 
"courses.location_name", 
"CONCAT(first_name,' ',surname)" 
);

/* Indexed column (used for fast and accurate table cardinality) */
$sIndexColumn = "leads.lead_id";

/* DB table to use */
$sTable = "courses";

$sJoin = 'LEFT JOIN leads ON leads.lead_get_course_id = courses.course_id';
$sJoin = 'LEFT JOIN clients ON clients.client_id = courses.course_get_client_id';

/* Database connection information */
$gaSql['user']       = "root";
$gaSql['password']   = "tommy";
$gaSql['db']         = "testingsiasite";
$gaSql['server']     = "localhost";


/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
 * If you just want to use the basic configuration for DataTables with PHP server-side, there is
 * no need to edit below this line
 */

/* 
 * MySQL connection
 */
$gaSql['link'] =  mysql_pconnect( $gaSql['server'], $gaSql['user'], $gaSql['password']  ) or
    die( 'Could not open connection to server' );

mysql_select_db( $gaSql['db'], $gaSql['link'] ) or 
    die( 'Could not select database '. $gaSql['db'] );


/* 
 * Paging
 */
$sLimit = "";
if ( isset( $_GET['iDisplayStart'] ) && $_GET['iDisplayLength'] != '-1' )
{
    $sLimit = "LIMIT ".mysql_real_escape_string( $_GET['iDisplayStart'] ).", ".
        mysql_real_escape_string( $_GET['iDisplayLength'] );
}


/*
 * Ordering
 */
if ( isset( $_GET['iSortCol_0'] ) )
{
    $sOrder = "ORDER BY  ";
    for ( $i=0 ; $i<intval( $_GET['iSortingCols'] ) ; $i++ )
    {
        if ( $_GET[ 'bSortable_'.intval($_GET['iSortCol_'.$i]) ] == "true" )
        {
            $sOrder .= $aColumns[ intval( $_GET['iSortCol_'.$i] ) ]."
                ".mysql_real_escape_string( $_GET['sSortDir_'.$i] ) .", ";
        }
    }

    $sOrder = substr_replace( $sOrder, "", -2 );
    if ( $sOrder == "ORDER BY" )
    {
        $sOrder = "";
    }
}

/* 
 * Filtering
 * NOTE this does not match the built-in DataTables filtering which does it
 * word by word on any field. It's possible to do here, but concerned about efficiency
 * on very large tables, and MySQL's regex functionality is very limited
 */


 /*  */
 /*  */
$sWhere = "";
    if ( isset($_GET['sSearch']) && $_GET['sSearch'] != "" )
    {
            $sWhere = "WHERE (";
            for ( $i=0 ; $i<count($aColumns) ; $i++ )
            {
                    $sWhere .= $aColumns[$i]." LIKE '%".mysql_real_escape_string( $_GET['sSearch'] )."%' OR ";
            }
            $sWhere = substr_replace( $sWhere, "", -3 );
            $sWhere .= " AND checked_by_admin='No'";
            $sWhere .= ')';
    }else{
            $sWhere = "WHERE checked_by_admin='No'";
 }

/* Individual column filtering */
for ( $i=0 ; $i<count($aColumns) ; $i++ )
{
    if ( $_GET['bSearchable_'.$i] == "true" && $_GET['sSearch_'.$i] != '' )
    {
        if ( $sWhere == "" )
        {
            $sWhere = "WHERE ";
        }
        else
        {
            $sWhere .= " AND ";
        }
        $sWhere .= $aColumns[$i]." LIKE '%".mysql_real_escape_string($_GET['sSearch_'.$i])."%' ";
    }
}   

/*
 * SQL queries
 * Get data to display
 */
    if($sWhere != ""):
        $sWhere .= " AND checked_by_admin='No'";
    endif;
$sQuery = "
    SELECT SQL_CALC_FOUND_ROWS ".str_replace(" , ", " ", implode(", ", $aColumns))."
    FROM $sTable
    $sJoin
    $sWhere
    $sOrder
    $sLimit
";
    $rResult = mysql_query( $sQuery, $gaSql['link'] ) or die(mysql_error());

/* Data set length after filtering */
$sQuery = "
    SELECT FOUND_ROWS()
";
$rResultFilterTotal = mysql_query( $sQuery, $gaSql['link'] ) or die(mysql_error());
$aResultFilterTotal = mysql_fetch_array($rResultFilterTotal);
$iFilteredTotal = $aResultFilterTotal[0];

/* Total data set length */
$sQuery = "
    SELECT COUNT(".$sIndexColumn.")
    FROM   $sTable
";
$rResultTotal = mysql_query( $sQuery, $gaSql['link'] ) or die(mysql_error());
$aResultTotal = mysql_fetch_array($rResultTotal);
$iTotal = $aResultTotal[0];


/*
 * Output
 */
$output = array(
    "sEcho" => intval($_GET['sEcho']),
    "iTotalRecords" => $iFilteredTotal,  // HERE FOR MASK TOTAL ENTRY not necerrary for others customers
    "iTotalDisplayRecords" => $iFilteredTotal,
    "aaData" => array()
);

while ( $aRow = mysql_fetch_array( $rResult ) )
{
    $row = array();
    for ( $i=0 ; $i<count($aColumns) ; $i++ )
    {
        if ( $aColumns[$i] == "version" )
        {
            /* Special output formatting for 'version' column */
            $row[] = ($aRow[ $aColumns[$i] ]=="0") ? '-' : $aRow[ $aColumns[$i] ];
        }
        else if ( $aColumns[$i] != ' ' )
        {
            /* General output */
            $row[] = $aRow[ $aColumns[$i] ];
        }
    }
    $row[] = "<span style='cursor:pointer'><img src='../images/more-info.png' alt='more info' onClick='javascript:my_onclick({$row[0]});'/></span>";
    $row[] = "<a href='../leads/actions/approve-lead.php?lead_id={$row[0]}'><img src='../images/approve.png' alt='' /></a>";
    $row[] = "<a href='../leads/actions/delete-lead.php?lead_id={$row[0]}' class='delete_link'><img src='../images/delete.png' alt='' /></a>";
    $output['aaData'][] = $row;
}

echo json_encode( $output );
?>

为什么我得到这个错误的任何亮点都会很棒!

1 个答案:

答案 0 :(得分:3)

好吧,加入将无法使用该PHP代码。即使我不得不在相同的情况下挣扎,直到我最终决定创建我自己的连接类来处理数据表,我正在考虑修改它以供每个人使用并释放它。但是既然你正面临这个问题,那么我提出的课程对我来说没有任何瑕疵,虽然目前情况不是很完美,但是我给出的代码认为它可能对你有帮助。

class DataTable {

    protected $_sTable;
    protected $_aColumns = array();
    protected $_sJoin = '';
    protected $_sWhere_0 = '';
    protected $_sGroupBy = '';
    protected $_sIndexColumn = 'id';
    protected $_iFilteredTotal;
    protected $_iTotal;
    protected $_iResult;
    protected static $_dbh;

    public function __construct($sTable, array $aColumns, $sJoin = '', $sWhere_0 = '', $sGroupBy = '', $sIndexColumn = '') {
        //This is PDO object for database connection.
        if(!isset(self::$_dbh)) self::$_dbh = Config_Database::getInstance();
        $this->_sTable = $sTable;
        $this->_aColumns = $aColumns;
        if($sJoin != '') $this->_sJoin = $sJoin;
        if($sWhere_0 != '') $this->_sWhere_0 = $sWhere_0;
        if($sGroupBy != '') $this->_sGroupBy = $sGroupBy;
        if($sIndexColumn != '') $this->_sIndexColumn = $sIndexColumn;
        $this->sQuery();
    }

    protected function sLimit() {
        if ( isset( $_GET['iDisplayStart'] ) && $_GET['iDisplayLength'] != '-1' ) {
             $sLimit = ' LIMIT ' . intval($_GET['iDisplayStart']) . ', ' . intval($_GET['iDisplayLength']);
        } else {
             $sLimit = '';
        }
        return $sLimit;
    }

    protected function sOrder() {
        $sOrder = '';
        if ( isset( $_GET['iSortCol_0'] ) ) {
             $sOrder = ' ORDER BY  ';
             for ( $i=0 ; $i<intval( $_GET['iSortingCols'] ) ; $i++ ) {
                if ( $_GET[ 'bSortable_'.intval($_GET['iSortCol_'.$i]) ] == 'true' ) {
                     $sOrder .= $this->_aColumns[ intval( $_GET['iSortCol_'.$i] ) ].' '.$_GET['sSortDir_'.$i] .', ';
                }
             }
             $sOrder = substr_replace( $sOrder, '', -2 );
             if ( $sOrder == ' ORDER BY' ) {
                  $sOrder = '';
             }  
        }
        return $sOrder;
    }

    protected function sWhere() {
        $sWhere = '';
        if ( $_GET['sSearch'] != '' ) {
             $sWhere = ' WHERE (';
             for ( $i=0 ; $i<count($this->_aColumns) ; $i++ ) {
                if ( $_GET['bSearchable_'.$i] == "true" ) {
                     $sWhere .= $this->_aColumns[$i]." LIKE '%". $_GET['sSearch'] ."%' OR ";
                }
             }
             $sWhere = substr_replace( $sWhere, "", -3 );
             $sWhere .= ')';
        }
        /* Conditions */
        if($this->_sWhere_0 != '') {
            if($sWhere != '') {
                $sWhere .= ' AND '.$this->_sWhere_0;    
            } else {
                $sWhere .= ' WHERE '.$this->_sWhere_0;
            }
        }
        /* Individual column filtering */
        for ( $i=0 ; $i<count($this->_aColumns) ; $i++ ) {
            if ( $_GET['bSearchable_'.$i] == "true" && $_GET['sSearch_'.$i] != '' ) {
                if ( $sWhere == '' ) {
                    $sWhere = 'WAHERE ';
                } else {
                    $sWhere .= ' AND ';
                }
                $sWhere .= $this->_aColumns[$i]." LIKE '%".$_GET['sSearch_'.$i]."%' ";
            }
        }
        return $sWhere;
    }

    protected function sQuery() {
        $sQuery = "SELECT SQL_CALC_FOUND_ROWS ".str_replace(" , ", " ", implode(", ", $this->_aColumns)).' FROM '.
        $this->_sTable.
        $this->_sJoin.
        $this->sWhere().
        $this->_sGroupBy.
        $this->sOrder().
        $this->sLimit();
        $sth = self::$_dbh->query($sQuery);
        $this->_iResult = $sth->fetchAll(PDO::FETCH_NUM);
        /* Data set length after filtering */
        $sQuery = 'SELECT FOUND_ROWS()';
        $sth = self::$_dbh->query($sQuery);
        $aResultFilterTotal = $sth->fetchAll(PDO::FETCH_NUM);
        $this->_iFilteredTotal = $aResultFilterTotal[0][0];
        /* Total data set length */
        $sQuery = 'SELECT COUNT('.$this->_sIndexColumn.') FROM '.$this->_sTable;
        $sth = self::$_dbh->query($sQuery);
        $aResultTotal = $sth->fetchAll(PDO::FETCH_NUM);
        $this->_iTotal = $aResultTotal[0][0];
        return $this;
    }

    public function aaData() {
        $output = array(
            "sEcho" => intval($_GET['sEcho']),
            "iTotalRecords" => $this->_iTotal,
            "iTotalDisplayRecords" => $this->_iFilteredTotal,
            "aaData" => array()
        );
        return $output;
    }

    public function iResult() {
        return $this->_iResult;
    }
}

现在,当我需要访问数据表时,它将通过创建上述DataTable对象的实例来工作。

$sTable = 'table1';
$aColumns = array('table1.column1', 'table1.colmun2', 'table2.column1', 'table2.column2', 'table3.column1');
//Put your logic of join over here, if you don;t have join just leave it empty
$sJoin = '';
//Put your condition over here, if you don;t have any leave it empty.
$sWhere = '';
$dataTable = new DataTable($sTable, $aColumns, $sJoin, $sWhere);
$output = $dataTable->aaData();
$iResult = $dataTable->iResult();
//Change Columns attribute and values
foreach($iResult as $k => $v) {
    $iResult[$k][3] = //Change 2nd row with whatever content you like.
}
$output['aaData'] = $iResult;
echo json_encode($output);

我的代码适用于任意数量的表中的任意数量的连接,但是当我有时间时,它仍然需要处理一些限制。

希望它对您有用:),

更新:您应该为代码做些什么。

//Create new PDO connection.
$host = 'localhoost';
$database = 'database';
$username = 'username';
$password = 'password';
$sDatabase = new PDO('mysql:host='.$host.';dbname='.$database,$username,$password);
//for the database to work with the class change the code in constructor with the below one.
public function __construct($sDatabase, $sTable, array $aColumns, $sJoin = '', $sWhere_0 = '', $sGroupBy = '', $sIndexColumn = '') {
    if(!isset(self::$_dbh)) self::$_dbh = $sDatabase;
    $this->_sTable = $sTable;
    $this->_aColumns = $aColumns;
    if($sJoin != '') $this->_sJoin = $sJoin;
    if($sWhere_0 != '') $this->_sWhere_0 = $sWhere_0;
    if($sGroupBy != '') $this->_sGroupBy = $sGroupBy;
    if($sIndexColumn != '') $this->_sIndexColumn = $sIndexColumn;
    $this->sQuery();
}
//Datatable config and instance.
$sTable = 'courses';
$aColumns = array(     
"leads.lead_id", 
"leads.date_time", 
"clients.username", 
"courses.course_type", 
"courses.location_name", 
"CONCAT(first_name,' ',surname) as full_name" 
);
$sJoin = ' LEFT JOIN leads ON leads.lead_get_course_id = courses.course_id';
$sJoin .= ' LEFT JOIN clients ON clients.client_id = courses.course_get_client_id';
$sWhere = "checked_by_admin='No'";
$dataTable = new DataTable($sDatabase, $sTable, $aColumns, $sJoin, $sWhere);
$output = $dataTable->aaData();
$iResult = $dataTable->iResult();
$output['aaData'] = $iResult;
echo json_encode($output);

如果您还有任何问题,请告诉我