【问题标题】:Simplification of SQL QuerySQL查询的简化
【发布时间】:2021-07-09 21:15:09
【问题描述】:

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

这是一个 SQLFiddle 链接,您可以在其中找到表和我的解决方案:http://sqlfiddle.com/#!9/f2303f/2。或者,这里是架构构建:

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

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

【问题讨论】:

  • 请解释查询应该做什么。
  • @GordonLinoff 公平点。添加到帖子顶部。

标签: mysql sql database join select


【解决方案1】:

您可以左连接完成聚合的单个派生表。

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 中的反引号。

【讨论】:

  • 这正是我想要的。它不仅有效,而且我觉得我从你的解释中学到了很多东西。非常感谢。已回答。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-11-12
  • 1970-01-01
  • 2010-12-31
  • 1970-01-01
  • 2021-01-11
  • 1970-01-01
相关资源
最近更新 更多