Mysql SQL查询的简化

Mysql SQL查询的简化,mysql,sql,database,join,select,Mysql,Sql,Database,Join,Select,SQL不是我的专长。我有一个工作查询,可以完成我需要的,但我知道必须有一个更干净的方法来实现我的目标 查询应返回: - Name - Date of most recent donation (if any) - Political Party guess as: R, D, or U, where: - R = Likely Republican (more republican donations than other donations) - D = Likely D

SQL不是我的专长。我有一个工作查询,可以完成我需要的,但我知道必须有一个更干净的方法来实现我的目标

查询应返回:

 - Name
 - Date of most recent donation (if any)
 - Political Party guess as: R, D, or U, where:
    - R = Likely Republican (more republican donations than other donations)
    - D = Likely Democrat (more democrat donations than other donations)
    - U = Undtermined (no donations on record, or R and D are tied for first place.
- Address
这里有一个SQLFIDLE链接,您可以在其中找到表和我的解决方案:。或者,以下是架构构建:

CREATE TABLE People (
ID INT UNSIGNED  DEFAULT '0000' NOT NULL,
Name  CHAR(20)      DEFAULT ''     NOT NULL,
Address   CHAR(40)      DEFAULT ''     NOT NULL,
PRIMARY KEY(ID));

INSERT INTO People VALUES
(1, "Name1", "Idaho"),
(2, "Name2","UCLA"),
(3, "Name3", "Carolina"),
(4, "Name4", "Portland");

CREATE TABLE Donations (
ID INT UNSIGNED  DEFAULT '0000' NOT NULL,
People_ID  INT UNSIGNED  DEFAULT '0000' NOT NULL,
Donation_Date   DATE  NOT NULL,
Party   INT SIGNED  DEFAULT '0000' NOT NULL,
PRIMARY KEY(ID));

INSERT INTO Donations VALUES
#Name1
(1, 1, "2000-06-23", 1), (2, 1, "2000-06-24",-1),

#Name2
(3, 2, "2001-06-25", 1),(4, 2, "2001-06-26", 1),

# Name3
(5, 3, "2002-06-26", -1),(6, 3, "2002-06-27", -1);

#Name4
#None
以下是查询:

SELECT Name, 
  IFNULL(donation_date, 'None') as 'Recent Donation', 
  IFNULL(voting_guess, "U") as 'Party Guess', 
  Address
FROM people p

LEFT JOIN donations on donations.people_id = p.id AND donations.donation_date = (
  SELECT MAX(donation_date) 
  FROM donations
  WHERE donations.people_id = p.id)
  
LEFT JOIN 
  (SELECT people_id, 
    (CASE
       WHEN SUM(party) > 0 THEN "R"
       WHEN SUM(party) < 0 THEN "D"
     END
    ) AS voting_guess
    FROM donations
    GROUP BY people_id
  ) voting ON P.id = voting.people_id

具体来说,我想尝试将后两个左连接压缩为一个。有什么建议吗?

您可以左键联接一个完成聚合的派生表

SELECT p1.name,
       coalesce(x1.donation_date, 'None') `Recent Donation`,
       coalesce(x1.voting_guess, 'U') `Party Guess`,
       p1.address
       FROM people p1
            LEFT JOIN (SELECT d1.people_id,
                              max(d1.donation_date) donation_date,
                              CASE
                                WHEN sum(d1.party) > 0 THEN
                                  'R'
                                WHEN sum(d1.party) < 0 THEN
                                  'D'
                              END voting_guess
                              FROM donations d1
                              GROUP BY d1.people_id) x1
                      ON x1.people_id = p1.id;

而且,您还应该学习在尽可能接近标准SQL的情况下使用适当的引号,以在移植到另一个DBMS时最大限度地减少兼容性问题。对于文字,仅使用单引号,对于文字,仅使用单引号。对于标识符,仅使用回标记,对于标识符,仅使用回标记。不要使用双引号。在标准SQL和许多其他DBMS中,双引号用于标识符,如MySQL中的回号。

请解释查询应该做什么。@GordonLinoff Fair point。添加到帖子顶部。这正是我要找的。这不仅有效,而且我觉得我从你的解释中学到了很多。非常感谢。回答。