我可以对这些MySQL查询进行哪些小的调整以获得我需要的结果?

时间:2017-05-30 05:22:39

标签: mysql sql database

我有一个MySQL数据库,其中包含表格'人物'问题'以及'答案'。我试图获得一些易于阅读的结果。 我有这个问题:

SELECT CONCAT(people.firstName, ' ', people.lastName) as Name, 
people.emailAddress,
(CASE questions.fruit 
    WHEN 'apple' THEN 'YES'
    ELSE ''
END) as Apple,
(CASE questions.fruit 
    WHEN 'orange' THEN 'YES'
    ELSE ''
END) as Orange,
(CASE questions.fruit 
    WHEN 'banana' THEN 'YES'
    ELSE ''
END) as Banana
From answers
Join questions ON answers.fruitID = questions.fruitID 
JOIN people ON questions.person = people.person 
WHERE questions.questionnaire = '24' 
ORDER BY people.person

产生这个结果:

    +------------------+--------------------+-------+--------+--------+
    |       Name       |    emailAddress    | Apple | Orange | Banana |
    +------------------+--------------------+-------+--------+--------+
    | Harry Potter     | hpotter@gmail.com  | YES   |        |        |
    | Harry Potter     | hpotter@gmail.com  | YES   |        |        |
    | Harry Potter     | hpotter@gmail.com  | YES   |        |        |
    | Ron Weasley      | rweasley@gmail.com | YES   |        |        |
    | Hermione Granger | hgranger@gmail.com | YES   | YES    |        |
    | Hermione Granger | hgranger@gmail.com | YES   |        |        |
    | Hermione Granger | hgranger@gmail.com | YES   |        |        |
    | Severus Snape    | ssnape@gmail.com   | YES   | YES    |        |
    | Remus Lupin      | rlupin@gmail.com   | YES   |        |        |
    | Viktor Krum      | vkrum@gmail.com    | YES   |        |        |
    | Molly Weasley    | mweasley@gmail.com | YES   | YES    |        |
    | Oliver Wood      | owood@gmail.com    | YES   |        |        |
    | Oliver Wood      | owood@gmail.com    |       |        | YES    |
    +------------------+--------------------+-------+--------+--------+

这很棒。它具有我需要的所有信息,但是,如果每个人只有一行并且他们选择的所有成果(即使他们多次回答)都显示在那一行上,那将是理想的。我无法弄清楚如何让小组去做我想做的事情。像这样:

+------------------+--------------------+-------+--------+--------+
|       Name       |    emailAddress    | Apple | Orange | Banana |
+------------------+--------------------+-------+--------+--------+
| Harry Potter     | hpotter@gmail.com  | YES   |        |        |
| Ron Weasley      | rweasley@gmail.com | YES   |        |        |
| Hermione Granger | hgranger@gmail.com | YES   | YES    |        |
| Severus Snape    | ssnape@gmail.com   | YES   | YES    |        |
| Remus Lupin      | rlupin@gmail.com   | YES   |        |        |
| Viktor Krum      | vkrum@gmail.com    | YES   |        |        |
| Molly Weasley    | mweasley@gmail.com | YES   | YES    |        |
| Oliver Wood      | owood@gmail.com    | YES   |        | YES    |
+------------------+--------------------+-------+--------+--------+

因此,上述理想结果会忽略人们对同一水果的多个答案。但是,在某些情况下,我想知道是否有人多次回答相同的水果。所以,我也得到了这个问题:

SELECT CONCAT(people.firstName, ' ', people.lastName) as Name, 
people.emailAddress,
SUM(CASE questions.fruit 
    WHEN 'apple' THEN 1
    ELSE 0
END) as 'AppleCount',
SUM(CASE questions.fruit 
    WHEN 'orange' THEN 1
    ELSE 0
END) as 'OrangeCount',
SUM(CASE questions.fruit 
    WHEN 'banana' THEN 1
    ELSE 0
END) as 'BananaCount'
From answers
Join questions ON answers.fruitID = questions.fruitID 
JOIN people ON questions.person = people.person
WHERE questions.questionnaire = '24'
GROUP BY people.person 
ORDER BY people.person

产生类似这样的东西:

+------------------+--------------------+---------+---------+--------+
|       Name       |    emailAddress    |  Apple  | Orange  | Banana |
+------------------+--------------------+---------+---------+--------+
| Harry Potter     | hpotter@gmail.com  | 3       | 0       | 0      |
| Ron Weasley      | rweasley@gmail.com | 1       | 0       | 0      |
| Hermione Granger | hgranger@gmail.com | 3       | 1       | 0      |
| Severus Snape    | ssnape@gmail.com   | 1       | 1       | 0      |
| Remus Lupin      | rlupin@gmail.com   | 1       | 0       | 0      |
| Viktor Krum      | vkrum@gmail.com    | 1       | 0       | 0      |
| Molly Weasley    | mweasley@gmail.com | 1       | 1       | 0      |
| Oliver Wood      | owood@gmail.com    | 1       | 0       | 1      |
+------------------+--------------------+---------+---------+--------+

这也很棒,但通过一些改进可能会更好。首先(真正的问题)是,当一个人还没有答案,但他们确实存在于问题表中时(因为我已经将调查问卷发给他们),他们根本不会出现上述问题。我想在结果中列出它们,它们只是没有选择任何水果。其次,我希望" 0" s只是空白。所以它看起来像这样:

+------------------+--------------------+---------+---------+--------+
|       Name       |    emailAddress    |  Apple  | Orange  | Banana |
+------------------+--------------------+---------+---------+--------+
| Harry Potter     | hpotter@gmail.com  | 3       |         |        |
| Ron Weasley      | rweasley@gmail.com | 1       |         |        |
| Hermione Granger | hgranger@gmail.com | 3       | 1       |        |
| Severus Snape    | ssnape@gmail.com   | 1       | 1       |        |
| Remus Lupin      | rlupin@gmail.com   | 1       |         |        |
| Viktor Krum      | vkrum@gmail.com    | 1       |         |        |
| Molly Weasley    | mweasley@gmail.com | 1       | 1       |        |
| Oliver Wood      | owood@gmail.com    | 1       |         | 1      |
| Argus Filch      | afilch@gmail.com   |         |         |        |
+------------------+--------------------+---------+---------+--------+

关于如何获得这两个预期结果的任何想法?

编辑:处理样本数据......

3 个答案:

答案 0 :(得分:0)

我认为透视查询可以提供您想要的输出。在下面的查询中,我GROUP BY连接的名称和电子邮件地址。这里的关键点是我们采用类似于您在原始查询中使用的MAX表达式的CASE

SELECT
    CONCAT(people.firstName, ' ', people.lastName) AS Name,
    people.emailAddress,
    MAX(CASE WHEN questions.fruit = 'apple'  THEN 'YES' END) AS Apple,
    MAX(CASE WHEN questions.fruit = 'orange' THEN 'YES' END) AS Orange,
    MAX(CASE WHEN questions.fruit = 'banana' THEN 'YES' END) AS Banana
FROM answers
LEFT JOIN questions
    ON answers.fruitID = questions.fruitID 
LEFT JOIN people
    ON questions.person = people.person AND
       questions.questionnaire = '24' 
GROUP BY
    CONCAT(people.firstName, ' ', people.lastName),   -- not ANSI compliant, but should
    people.emailAddress                               -- work with MySQL
ORDER BY Name

请注意,我不知道你为什么要加入answers表。如果你已经包含了一些样本数据,那么这可能是显而易见的。

如果你想获得每个水果的计数,那么你可以使用以下SELECT,其余的查询相同:

SELECT
    CONCAT(people.firstName, ' ', people.lastName) AS Name,
    people.emailAddress,
    SUM(CASE WHEN questions.fruit = 'apple'  THEN 1 ELSE 0 END) AS Apple,
    SUM(CASE WHEN questions.fruit = 'orange' THEN 1 ELSE 0 END) AS Orange,
    SUM(CASE WHEN questions.fruit = 'banana' THEN 1 ELSE 0 END) AS Banana

答案 1 :(得分:0)

SELECT CONCAT(people.firstName, ' ', people.lastName) as Name, 
people.emailAddress,
sum((CASE questions.fruit 
    WHEN 'apple' THEN 1
    ELSE  NULL
END) ) as Apple,
sum((CASE questions.fruit 
    WHEN 'orange' THEN 1
    ELSE NULL
END)) as Orange,
sum((CASE questions.fruit 
    WHEN 'banana' THEN 1
    ELSE NULL 
END)) as Banana
From people
LEFT JOIN ON questions questions.person = people.person 
LEFT Join answers  ON answers.fruitID = questions.fruitID 
WHERE questions.questionnaire = '24' 
GROUP BY CONCAT(people.firstName, ' ', people.lastName), people.emailAddress
ORDER BY name, people.emailAddress

答案 2 :(得分:0)

您应该使用左连接而不是连接来获取没有任何答案的Argus。并将子查询设为0,因为总和结果永远不会为空。

SELECT Name, CASE WHEN AppleCount = 0 THEN '' ELSE AppleCount END, 
CASE WHEN OrangeCount= 0 THEN '' ELSE OrangeCount END,
CASE WHEN BananaCount= 0 THEN '' ELSE BananaCount END FROM (
  SELECT CONCAT(people.firstName, ' ', people.lastName) as Name, 
  people.emailAddress,
  SUM(CASE questions.fruit 
     WHEN 'apple' THEN 1
     ELSE 0
  END) as 'AppleCount',
  SUM(CASE questions.fruit 
     WHEN 'orange' THEN 1
     ELSE 0
  END) as 'OrangeCount',
  SUM(CASE questions.fruit 
   WHEN 'banana' THEN 1
   ELSE 0
  END) as 'BananaCount'
  From people 
  LEFT JOIN ON answers questions.person = people.person
  LEFT JOIN questions ON answers.fruitID = campaign.fruitID 
  WHERE questions.questionnaire = '24'
  GROUP BY people.person 
  ORDER BY people.person) TableA

糟透了我的坏,因为你想要人们显示人们应该在答案表上而不是在答案表上。

相关问题