2016-05-02 7 views
2

Попытка JOIN 2 таблицы для подсчета этнической принадлежности на основе 1-го стола (student_schedule), , где учащийся может появиться более 1 раза. Таблица 2 (bday) только что студент показывает 1 time by ID с student's ethnicity. Я использую LEFT JOIN, потому что иногда у меня может быть недостающий студент в таблице bday, и они не будут учитываться (поскольку их этническая принадлежность не была объявлена).Sub Query Count

SELECT bday.Ethnicity, ROUND(COUNT(DISTINCT student_schedule.ID)/(SELECT 
COUNT(DISTINCT student_schedule.ID) FROM student_schedule 
WHERE student_schedule.Course LIKE 'AS%')*100,2) AS "% of AS Population", 
(SELECT COUNT(DISTINCT student_schedule.ID) FROM student_schedule AS 
"Total Student Population") 
FROM student_schedule LEFT JOIN bday ON student_schedule.ID=bday.ID WHERE  
student_schedule.Course LIKE 'AS%' GROUP BY bday.Ethnicity 
ORDER BY COUNT(DISTINCT student_schedule.ID) DESC 

В результате получилось 3 колонки (этническая принадлежность,% от численности населения в населенном пункте, общая численность учащихся). enter image description here

Для того, чтобы сравнить процент студентов с курса Like 'AS%', Я хотел бы добавить еще один столбец, который дает мне этничность для всей школы, сгруппированных по национальности. Другими словами, 32% белых студентов взяли AS против белого населения школы - 30%. Данные взяты из таблицы 2 (bday), в которой перечислены все учащиеся с их этнической принадлежностью. Это должно быть что-то вроде

SELECT COUNT(bday.Ethnicity) 
FROM student_schedule 
LEFT JOIN bday ON student_schedule.ID=bday.ID. 

Я застрял с GROUP function необходимо для COUNT разделить на категории (White, Black,...).

В идеале, мой результат был бы ...

enter image description here

Любой помощь будет оценена.

ответ

1

Вы могли бы попробовать что-то вроде этого:

<?php 
//NOTE: I AM USING PDO FOR SIMPLICITY... BUT ANY OTHER DBAL WORKS AS WELL... 
//DATABASE CONNECTION CONFIGURATION: 
defined("HOST")  or define("HOST", "localhost");   //REPLACE WITH YOUR DB-HOST 
defined("DBASE") or define("DBASE", "_TEST_");    //REPLACE WITH YOUR DB NAME 
defined("USER")  or define("USER", "root");    //REPLACE WITH YOUR DB-USER 
defined("PASS")  or define("PASS", "root");    //REPLACE WITH YOUR DB-PASS 



try { 
    $dbh   = new PDO('mysql:host='.HOST.';dbname='. DBASE,USER,PASS); 
    $dbh->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION); 


    $sql   = 'SELECT COUNT(SS.ID) AS "Global_Student_Population" FROM student_schedule AS SS '; 
    $stmt   = $dbh->prepare($sql); 
    $stmt->execute(); 
    $result   = $stmt->fetchAll(PDO::FETCH_COLUMN); 
    $intAllStudents = (int)$result[0]; 

    $sql   = " SELECT BD.Ethnicity, {$intAllStudents} AS Global_Student_Population, 
         COUNT(DISTINCT SS.ID) AS Ethnic_Student_Population, 
         ROUND(COUNT(DISTINCT SS.ID)*100/{$intAllStudents}) AS '%_of_AS_Population' 
         FROM student_schedule AS SS 
         LEFT JOIN bday AS BD ON SS.ID=BD.ID 
         WHERE SS.Course LIKE 'AS%' GROUP BY BD.Ethnicity"; 

    $stmt   = $dbh->prepare($sql); 
    $stmt->execute(); 
    $result   = $stmt->fetchAll(); 

     var_dump($result); 
     var_dump($intAllStudents); 

    //GARBAGE COLLECTION 
    $dbh  = null; 
}catch(PDOException $e){ 
    echo $e->getMessage(); 
} 

Мой var_dump() показывает что-то вроде этого:

 array (size=3) 
     0 => 
     array (size=8) 
      'Ethnicity' => string 'Black' (length=5) 
      0 => string 'Black' (length=5) 
      'Global_Student_Population' => string '10' (length=2) 
      1 => string '10' (length=2) 
      'Ethnic_Student_Population' => string '3' (length=1) 
      2 => string '3' (length=1) 
      '%_of_AS_Population' => string '30' (length=2) 
      3 => string '30' (length=2) 
     1 => 
     array (size=8) 
      'Ethnicity' => string 'Hispanic' (length=8) 
      0 => string 'Hispanic' (length=8) 
      'Global_Student_Population' => string '10' (length=2) 
      1 => string '10' (length=2) 
      'Ethnic_Student_Population' => string '1' (length=1) 
      2 => string '1' (length=1) 
      '%_of_AS_Population' => string '10' (length=2) 
      3 => string '10' (length=2) 
     2 => 
     array (size=8) 
      'Ethnicity' => string 'White' (length=5) 
      0 => string 'White' (length=5) 
      'Global_Student_Population' => string '10' (length=2) 
      1 => string '10' (length=2) 
      'Ethnic_Student_Population' => string '2' (length=1) 
      2 => string '2' (length=1) 
      '%_of_AS_Population' => string '20' (length=2) 
      3 => string '20' (length=2) 

А вот мой тест Таблица Определения: - - Структура таблицы для таблицы bday -

CREATE TABLE `bday` (
    `ID` int(11) NOT NULL, 
     `Ethnicity` varchar(255) NOT NULL 
    ) ENGINE=InnoDB AUTO_INCREMENT=11 DEFAULT CHARSET=utf8; 

    -- 
    -- Dumping data for table `bday` 
    -- 

    INSERT INTO `bday` (`ID`, `Ethnicity`) VALUES 
    (1, 'Black'), 
    (2, 'Black'), 
    (3, 'Black'), 
    (4, 'White'), 
    (5, 'Hispanic'), 
    (6, 'White'), 
    (7, 'Asian'), 
    (8, 'Hispanic'), 
    (9, 'White'), 
    (10, 'Black'); 

    -- 
    -- Indexes for dumped tables 
    -- 

    -- 
    -- Indexes for table `bday` 
    -- 
    ALTER TABLE `bday` 
     ADD PRIMARY KEY (`ID`); 

    -- 
    -- AUTO_INCREMENT for dumped tables 
    -- 

    -- 
    -- AUTO_INCREMENT for table `bday` 
    -- 
    ALTER TABLE `bday` 
     MODIFY `ID` int(11) NOT NULL AUTO_INCREMENT,AUTO_INCREMENT=11; 




    -- 
    -- Table structure for table `student_schedule` 
    -- 

    CREATE TABLE `student_schedule` (
    `ID` int(11) unsigned NOT NULL, 
     `Course` varchar(255) NOT NULL 
    ) ENGINE=InnoDB AUTO_INCREMENT=11 DEFAULT CHARSET=utf8; 

    -- 
    -- Dumping data for table `student_schedule` 
    -- 

    INSERT INTO `student_schedule` (`ID`, `Course`) VALUES 
    (1, 'AS'), 
    (2, 'AS'), 
    (3, 'EN'), 
    (4, 'EN'), 
    (5, 'AS'), 
    (6, 'AS'), 
    (7, 'EN'), 
    (8, 'EN'), 
    (9, 'AS'), 
    (10, 'AS'); 

    -- 
    -- Indexes for dumped tables 
    -- 

    -- 
    -- Indexes for table `student_schedule` 
    -- 
    ALTER TABLE `student_schedule` 
     ADD PRIMARY KEY (`ID`); 

    -- 
    -- AUTO_INCREMENT for dumped tables 
    -- 

    -- 
    -- AUTO_INCREMENT for table `student_schedule` 
    -- 
    ALTER TABLE `student_schedule` 
     MODIFY `ID` int(11) unsigned NOT NULL AUTO_INCREMENT,AUTO_INCREMENT=11; 
1

Ваш SQL немного грязный, Lets первый вновь построить его, чтобы сделать его более четким и читаемым:

SELECT bday.Ethnicity 
     , ROUND(
      COUNT(*)/(SELECT COUNT(DISTINCT ID) FROM student_schedule 
               WHERE Course LIKE 'AS%') 
      *100,2) AS "% of AS Population" 
FROM bday INNER JOIN student_schedule on bday.ID=student_schedule.ID 
WHERE student_schedule.Course LIKE 'AS%' 
GROUP BY bday.Ethnicity 

Обратите внимание здесь я использовал INNER JOIN, как это здесь лучше, если бы некоторые студенты, не Ethnicity заявленной вы получите свой процент, который имеет смысл (и может быть отфильтрованы в пункте WHERE)

Теперь мы хотим, чтобы добавить (count) студентов каждого Ethnicity из таблицы bday, чтобы сделать это, мы просто добавить Sub-Query к SELECT список:

SELECT bday.Ethnicity 
     , ROUND(
      COUNT(*)/(SELECT COUNT(DISTINCT ID) FROM student_schedule 
               WHERE Course LIKE 'AS%') 
      *100,2) AS "% of AS Population" 

     , ROUND(
      (SELECT COUNT(*) FROM bday a WHERE a.Ethnicity=bday.Ethnicity) 
      /(SELECT COUNT(*) FROM bday) 
      *100,2) AS "Ethnicity of School"   
FROM bday INNER JOIN student_schedule on bday.ID=student_schedule.ID 
WHERE student_schedule.Course LIKE 'AS%' 
GROUP BY bday.Ethnicity 

Примечание здесь я установил alias таблицы bday суб-запрос как a, чтобы избежать конфликтов с внешней bday стола при его использовании в пункте WHERE внутри подзапроса.

0

Иногда вам нужно начинать с самого начала, когда вы повесили трубку. Я решил начать с глобальных COUNTS, а затем использовать выражения CASE для подсчета WHERE. Я, наконец, получил его на работу так, как я needed.The решение, которое я придумал это:

SELECT bday.Ethnicity, ROUND(COUNT(DISTINCT CASE WHEN 
student_schedule.Course LIKE 'AS%' THEN student_schedule.ID END)/(SELECT 
COUNT(DISTINCT student_schedule.ID) FROM student_schedule WHERE 
student_schedule.Course LIKE 'AS%')*100,2) AS '% of AS Population', 
ROUND(COUNT(DISTINCT student_schedule.ID)/(SELECT COUNT(DISTINCT 
student_schedule.ID) FROM student_schedule)*100,2) AS '% of Student 
Population' 
FROM student_schedule INNER JOIN bday ON student_schedule.ID=bday.ID 
GROUP BY bday.Ethnicity 
ORDER BY COUNT(DISTINCT student_schedule.ID) DESC 

Результат: enter image description here