【问题标题】:SQL Select First, Second, Third, Fourth ,LastSQL 选择第一、第二、第三、第四、最后
【发布时间】:2014-07-23 07:20:06
【问题描述】:

我有一个会员数据库,其中包含居住在同一地址的人数。为了尽量减少邮寄时事通讯时的邮政开支,我想从数据库中选择唯一的地址,并将所有住在同一地址的人的姓名添加到同一标签上。我在Members 表中的字段是NamesAddressLine1AddressLine2SuburbStatePostcode

如果需要,我很高兴创建一个新表,其中包含名为FirstOfNameSecondOfNamesThirdOfNamesLastOfNames 的附加字段。在我的数据库中,居住在同一地址的最大人数为 5。

标签上所需输出的示例:

John Smith

Jane Smith

10 High Street

Beverly Hills, NSW 2000

非常感谢任何帮助,因为我在这方面遇到了很多困难。

非常感谢, 米卡

【问题讨论】:

    标签: sql database select group-by


    【解决方案1】:

    我假设您的理想目标是在单个复杂查询中获取最多五个姓名和一个地址。此示例在 PostgreSQL 中。您没有指定数据库,但我相信 ORACLE 和 SQLServer 中存在推论。您将不得不做出自己的调整。

    它有点乱,但它有效。简而言之,您使用 WINDOW 函数对每个唯一地址的多个名称进行排名。使用 WITH 子句按等级隔离每个名称。 LEFT JOIN 为少于五个名称的地址选择名称。

    示例表:

       DROP TABLE name_address;
    
       CREATE TABLE name_address
       (
       first_name CHARACTER VARYING (50)
       ,last_name CHARACTER VARYING (50)
       ,addr_line1 CHARACTER VARYING (50)
       ,city CHARACTER VARYING (50)
       ,state CHARACTER VARYING (2)
       ,zip  CHARACTER VARYING (5)
       )
       WITH (OIDS=TRUE);
       ALTER TABLE name_address OWNER TO your_name_here;
    

    样本数据:

       INSERT INTO name_address (first_name, last_name, addr_line1, city, state, zip) SELECT 'John', 'Smith', '10 High Street', 'Beverly Hills NSW 2000', 'CA', '90210';
       INSERT INTO name_address (first_name, last_name, addr_line1, city, state, zip) SELECT 'Jane', 'Smith', '10 High Street', 'Beverly Hills NSW 2000', 'CA', '90210';
       INSERT INTO name_address (first_name, last_name, addr_line1, city, state, zip) SELECT 'Jeff', 'Smith', '12 High Street', 'Beverly Hills NSW 2000', 'CA', '90210';
       INSERT INTO name_address (first_name, last_name, addr_line1, city, state, zip) SELECT 'Jean', 'Smith', '12 High Street', 'Beverly Hills NSW 2000', 'CA', '90210';
       INSERT INTO name_address (first_name, last_name, addr_line1, city, state, zip) SELECT 'Jenn', 'Smith', '12 High Street', 'Beverly Hills NSW 2000', 'CA', '90210';
       INSERT INTO name_address (first_name, last_name, addr_line1, city, state, zip) SELECT 'Jack', 'Smith', '12 High Street', 'Beverly Hills NSW 2000', 'CA', '90210';
       INSERT INTO name_address (first_name, last_name, addr_line1, city, state, zip) SELECT 'Josh', 'Smith', '12 High Street', 'Beverly Hills NSW 2000', 'CA', '90210';
    

    解决办法:

       WITH nr AS (SELECT DISTINCT first_name, last_name, addr_line1, city, state, zip, COUNT(*) OVER(PARTITION BY zip, state, city, addr_line1 ORDER BY zip, state, city, addr_line1, last_name, first_name) AS name_rank
       FROM name_address
       GROUP BY first_name, last_name, addr_line1, city, state, zip
       ORDER BY zip, state, city, addr_line1, name_rank)
       ,n1 AS(SELECT nr.first_name, nr.last_name, nr.addr_line1, nr.city, nr.state, nr.zip
       FROM nr
       WHERE nr.name_rank = 1)
       ,n2 AS(SELECT nr.first_name, nr.last_name, nr.addr_line1, nr.city, nr.state, nr.zip
       FROM nr
       WHERE nr.name_rank = 2)
       ,n3 AS(SELECT nr.first_name, nr.last_name, nr.addr_line1, nr.city, nr.state, nr.zip
       FROM nr
       WHERE nr.name_rank = 3)
       ,n4 AS(SELECT nr.first_name, nr.last_name, nr.addr_line1, nr.city, nr.state, nr.zip
       FROM nr
       WHERE nr.name_rank = 4)
       ,n5 AS(SELECT nr.first_name, nr.last_name, nr.addr_line1, nr.city, nr.state, nr.zip
       FROM nr
       WHERE nr.name_rank = 5)
       SELECT   DISTINCT n1.first_name
           , n1.last_name
           , n2.first_name
           , n2.last_name
           , n3.first_name
           , n3.last_name
           , n4.first_name
           , n4.last_name
           , n5.first_name
           , n5.last_name
           , na.addr_line1
           , na.city
           , na.state
           , na.zip
       FROM name_address AS na
       LEFT JOIN n1 ON n1.addr_line1 = na.addr_line1 AND n1.city = na.city AND n1.state = na.state AND n1.zip = na.zip
       LEFT JOIN n2 ON n2.addr_line1 = na.addr_line1 AND n2.city = na.city AND n2.state = na.state AND n2.zip = na.zip
       LEFT JOIN n3 ON n3.addr_line1 = na.addr_line1 AND n3.city = na.city AND n3.state = na.state AND n3.zip = na.zip
       LEFT JOIN n4 ON n4.addr_line1 = na.addr_line1 AND n4.city = na.city AND n4.state = na.state AND n4.zip = na.zip
       LEFT JOIN n5 ON n5.addr_line1 = na.addr_line1 AND n5.city = na.city AND n5.state = na.state AND n5.zip = na.zip;
    

    这是最终输出:

    “简”;“史密斯”;“约翰”;“史密斯”;“”;“”;“”;“”;“”;“”;“高街 10 号”;“2000 年新南威尔士州比佛利山庄”; "CA";"90210" “Jack”;“Smith”;“Jean”;“Smith”;“Jeff”;“Smith”;“Jenn”;“Smith”;“Josh”;“Smith”;“12 High Street”;“Beverly Hills NSW 2000";"CA";"90210"

    【讨论】:

      猜你喜欢
      • 2016-12-30
      • 2015-06-02
      • 1970-01-01
      • 1970-01-01
      • 2022-10-15
      • 2015-10-11
      • 2017-11-23
      • 2021-06-01
      • 1970-01-01
      相关资源
      最近更新 更多