Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/sql/81.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
PostgreSQL查询中的条件语句_Sql_Postgresql_Database Design_Many To Many_Greatest N Per Group - Fatal编程技术网

PostgreSQL查询中的条件语句

PostgreSQL查询中的条件语句,sql,postgresql,database-design,many-to-many,greatest-n-per-group,Sql,Postgresql,Database Design,Many To Many,Greatest N Per Group,我这里有三张桌子,分别是: person ( id int PRIMARY KEY ,fullname text) phonenumber ( id int PRIMARY KEY ,personid int REFERENCES person(id) ,phonetypeid REFERENCES phonetype(id) ,number text) phonetype ( id int PRIMARY KEY ,phonetype text) -- phonetype

我这里有三张桌子,分别是:

person (
  id int PRIMARY KEY
 ,fullname text)

phonenumber (
  id int PRIMARY KEY
 ,personid int REFERENCES person(id)
 ,phonetypeid REFERENCES phonetype(id)
 ,number text)

phonetype (
 id int PRIMARY KEY
,phonetype text) -- phonetype  'Home', 'Cell', 'Fax', 'Main' etc.
每个
都可以在
电话号码
表中存储多个号码,并且在
电话类型
表中具有不同的电话类型:

| fullname         | number        | phonetype |
| Erwin Macale     | (671)632-3909 | Home      |
| Erwin Macale     | (671)632-3909 | Cell      |
| Erwin Macale     | (671)632-3909 | Main      |
我只想显示具有以下条件的每个人的电话号码:

CREATE TEMP TABLE all_cell AS SELECT * FROM cell EXCEPT SELECT * FROM home;
CREATE TEMP TABLE all_main AS (SELECT * FROM main) EXCEPT (SELECT * FROM home UNION SELECT * FROM cell);
CREATE TEMP TABLE all_fax AS (SELECT * FROM fax) EXCEPT (SELECT * FROM home UNION SELECT * FROM cell UNION SELECT * FROM main);
CREATE TEMP TABLE all_work AS (SELECT * FROM work) EXCEPT (SELECT * FROM home UNION SELECT * FROM cell UNION SELECT * FROM main UNION SELECT * FROM fax);
CREATE TEMP TABLE all_neighbor AS (SELECT * FROM neighbor) EXCEPT (SELECT * FROM home UNION SELECT * FROM cell UNION SELECT * FROM main UNION SELECT * FROM fax UNION SELECT * FROM work);
CREATE TEMP TABLE all_other AS (SELECT * FROM other) EXCEPT (SELECT * FROM home UNION SELECT * FROM cell UNION SELECT * FROM main UNION SELECT * FROM fax UNION SELECT * FROM work UNION SELECT * FROM neighbor);
CREATE TEMP TABLE all_unknown AS (SELECT * FROM unknown) EXCEPT (SELECT * FROM home UNION SELECT * FROM cell UNION SELECT * FROM main UNION SELECT * FROM fax UNION SELECT * FROM work UNION SELECT * FROM neighbor UNION SELECT * FROM other);
  • 如果他有一个“Home”电话号码,只显示Home类型,删除所有其他电话号码
  • 如果他没有“家”号码,则只显示他的“手机”号码,然后删除所有其他(“传真”、“主”等)号码
  • 一个人可以没有电话号码
我创建了一个临时表,其中包含
全名、号码、电话类型
名为
可测试
,然后从这里分离所有电话类型号码,如:

CREATE TEMP TABLE home AS SELECT * FROM testable WHERE phonetype ILIKE 'home';
CREATE TEMP TABLE cell AS SELECT * FROM testable WHERE phonetype ilike 'cell';
CREATE TEMP TABLE main AS SELECT * FROM testable WHERE phonetype ilike 'main';
CREATE TEMP TABLE fax AS SELECT * FROM testable WHERE phonetype ilike 'fax';
CREATE TEMP TABLE work AS SELECT * FROM testable WHERE phonetype ilike 'work';
CREATE TEMP TABLE neighbor AS SELECT * FROM testable WHERE phonetype ilike 'neighbor';
CREATE TEMP TABLE other AS SELECT * FROM testable WHERE phonetype ilike 'other';
CREATE TEMP TABLE unknown AS SELECT * FROM testable WHERE phonetype ilike 'unknown';
然后创建另一组我认为满足上述条件的临时表:

CREATE TEMP TABLE all_cell AS SELECT * FROM cell EXCEPT SELECT * FROM home;
CREATE TEMP TABLE all_main AS (SELECT * FROM main) EXCEPT (SELECT * FROM home UNION SELECT * FROM cell);
CREATE TEMP TABLE all_fax AS (SELECT * FROM fax) EXCEPT (SELECT * FROM home UNION SELECT * FROM cell UNION SELECT * FROM main);
CREATE TEMP TABLE all_work AS (SELECT * FROM work) EXCEPT (SELECT * FROM home UNION SELECT * FROM cell UNION SELECT * FROM main UNION SELECT * FROM fax);
CREATE TEMP TABLE all_neighbor AS (SELECT * FROM neighbor) EXCEPT (SELECT * FROM home UNION SELECT * FROM cell UNION SELECT * FROM main UNION SELECT * FROM fax UNION SELECT * FROM work);
CREATE TEMP TABLE all_other AS (SELECT * FROM other) EXCEPT (SELECT * FROM home UNION SELECT * FROM cell UNION SELECT * FROM main UNION SELECT * FROM fax UNION SELECT * FROM work UNION SELECT * FROM neighbor);
CREATE TEMP TABLE all_unknown AS (SELECT * FROM unknown) EXCEPT (SELECT * FROM home UNION SELECT * FROM cell UNION SELECT * FROM main UNION SELECT * FROM fax UNION SELECT * FROM work UNION SELECT * FROM neighbor UNION SELECT * FROM other);
最后选择最后一组临时表的所有联合:

SELECT fullname, number, phonetype FROM (
    SELECT * FROM home
    UNION 
    SELECT * FROM all_cell
    UNION 
    SELECT * FROM all_main
    UNION 
    SELECT * FROM all_fax
    UNION 
    SELECT * FROM all_work
    UNION 
    SELECT * FROM all_neighbor
    UNION 
    SELECT * FROM all_other
    UNION 
    SELECT * FROM all_unknown
) AS t1
ORDER BY t1.fullname, t1.phonetype;
满足我的条件的步骤正确吗?
我仍然从一个人那里得到不同的phonetype值。

您费了很大的劲才得到这个查询可以提供给您的信息:

SELECT DISTINCT ON (p.fullname, p.id)
       p.fullname, n.number, t.phonetype
FROM   phonenumber n 
JOIN   person      p ON p.id = n.personid
JOIN   phonetype   t ON t.id = n.phonetypeid
LEFT   JOIN (
   VALUES
     (1, 'home')
    ,(2, 'cell')
    ,(3, 'main')
    ,(4, 'fax')
    ,(5, 'work')
    ,(6, 'neighbor')
    ,(7, 'other')
    ,(8, 'unknown')
   ) r(rnk, phonetype) USING (phonetype)
ORDER  BY p.fullname, p.id, r.rnk;
DISTINCT ON(p.fullname,p.id)
因为
fullname
可能不是唯一的。无论如何,我使用它来获取您在单个查询级别中似乎要查找的排序顺序

有关此相关答案中的的详细信息:

我在排名(
r.rnk
)信息后面附加了一个标签,使其与您的表格布局配合使用。但更好的是,您可以将以下内容永久添加到表
phonetype

ALTER TABLE phonetype ADD COLUMN rnk int;

UPDATE phonetype t
SET    rnk = r.rnk
FROM  (
       VALUES
         (1, 'home')
        ,(2, 'cell')
        ,(3, 'main')
        ,(4, 'fax')
        ,(5, 'work')
        ,(6, 'neighbor')
        ,(7, 'other')
        ,(8, 'unknown')
       ) r(rnk, phonetype)
WHERE   r.phonetype = t.phonetype;
然后您的查询变得更简单了:

SELECT DISTINCT ON (p.fullname, p.id)
       p.fullname, n.number, t.phonetype
FROM   phonenumber n 
JOIN   person      p ON p.id = n.personid
JOIN   phonetype   t ON t.id = n.phonetypeid
ORDER  BY p.fullname, p.id, t.rnk    -- add more columns to break ties (if any)

您费了很大的劲才得到这个查询可以提供的信息:

SELECT DISTINCT ON (p.fullname, p.id)
       p.fullname, n.number, t.phonetype
FROM   phonenumber n 
JOIN   person      p ON p.id = n.personid
JOIN   phonetype   t ON t.id = n.phonetypeid
LEFT   JOIN (
   VALUES
     (1, 'home')
    ,(2, 'cell')
    ,(3, 'main')
    ,(4, 'fax')
    ,(5, 'work')
    ,(6, 'neighbor')
    ,(7, 'other')
    ,(8, 'unknown')
   ) r(rnk, phonetype) USING (phonetype)
ORDER  BY p.fullname, p.id, r.rnk;
DISTINCT ON(p.fullname,p.id)
因为
fullname
可能不是唯一的。无论如何,我使用它来获取您在单个查询级别中似乎要查找的排序顺序

有关此相关答案中的的详细信息:

我在排名(
r.rnk
)信息后面附加了一个标签,使其与您的表格布局配合使用。但更好的是,您可以将以下内容永久添加到表
phonetype

ALTER TABLE phonetype ADD COLUMN rnk int;

UPDATE phonetype t
SET    rnk = r.rnk
FROM  (
       VALUES
         (1, 'home')
        ,(2, 'cell')
        ,(3, 'main')
        ,(4, 'fax')
        ,(5, 'work')
        ,(6, 'neighbor')
        ,(7, 'other')
        ,(8, 'unknown')
       ) r(rnk, phonetype)
WHERE   r.phonetype = t.phonetype;
然后您的查询变得更简单了:

SELECT DISTINCT ON (p.fullname, p.id)
       p.fullname, n.number, t.phonetype
FROM   phonenumber n 
JOIN   person      p ON p.id = n.personid
JOIN   phonetype   t ON t.id = n.phonetypeid
ORDER  BY p.fullname, p.id, t.rnk    -- add more columns to break ties (if any)

您费了很大的劲才得到这个查询可以提供的信息:

SELECT DISTINCT ON (p.fullname, p.id)
       p.fullname, n.number, t.phonetype
FROM   phonenumber n 
JOIN   person      p ON p.id = n.personid
JOIN   phonetype   t ON t.id = n.phonetypeid
LEFT   JOIN (
   VALUES
     (1, 'home')
    ,(2, 'cell')
    ,(3, 'main')
    ,(4, 'fax')
    ,(5, 'work')
    ,(6, 'neighbor')
    ,(7, 'other')
    ,(8, 'unknown')
   ) r(rnk, phonetype) USING (phonetype)
ORDER  BY p.fullname, p.id, r.rnk;
DISTINCT ON(p.fullname,p.id)
因为
fullname
可能不是唯一的。无论如何,我使用它来获取您在单个查询级别中似乎要查找的排序顺序

有关此相关答案中的的详细信息:

我在排名(
r.rnk
)信息后面附加了一个标签,使其与您的表格布局配合使用。但更好的是,您可以将以下内容永久添加到表
phonetype

ALTER TABLE phonetype ADD COLUMN rnk int;

UPDATE phonetype t
SET    rnk = r.rnk
FROM  (
       VALUES
         (1, 'home')
        ,(2, 'cell')
        ,(3, 'main')
        ,(4, 'fax')
        ,(5, 'work')
        ,(6, 'neighbor')
        ,(7, 'other')
        ,(8, 'unknown')
       ) r(rnk, phonetype)
WHERE   r.phonetype = t.phonetype;
然后您的查询变得更简单了:

SELECT DISTINCT ON (p.fullname, p.id)
       p.fullname, n.number, t.phonetype
FROM   phonenumber n 
JOIN   person      p ON p.id = n.personid
JOIN   phonetype   t ON t.id = n.phonetypeid
ORDER  BY p.fullname, p.id, t.rnk    -- add more columns to break ties (if any)

您费了很大的劲才得到这个查询可以提供的信息:

SELECT DISTINCT ON (p.fullname, p.id)
       p.fullname, n.number, t.phonetype
FROM   phonenumber n 
JOIN   person      p ON p.id = n.personid
JOIN   phonetype   t ON t.id = n.phonetypeid
LEFT   JOIN (
   VALUES
     (1, 'home')
    ,(2, 'cell')
    ,(3, 'main')
    ,(4, 'fax')
    ,(5, 'work')
    ,(6, 'neighbor')
    ,(7, 'other')
    ,(8, 'unknown')
   ) r(rnk, phonetype) USING (phonetype)
ORDER  BY p.fullname, p.id, r.rnk;
DISTINCT ON(p.fullname,p.id)
因为
fullname
可能不是唯一的。无论如何,我使用它来获取您在单个查询级别中似乎要查找的排序顺序

有关此相关答案中的的详细信息:

我在排名(
r.rnk
)信息后面附加了一个标签,使其与您的表格布局配合使用。但更好的是,您可以将以下内容永久添加到表
phonetype

ALTER TABLE phonetype ADD COLUMN rnk int;

UPDATE phonetype t
SET    rnk = r.rnk
FROM  (
       VALUES
         (1, 'home')
        ,(2, 'cell')
        ,(3, 'main')
        ,(4, 'fax')
        ,(5, 'work')
        ,(6, 'neighbor')
        ,(7, 'other')
        ,(8, 'unknown')
       ) r(rnk, phonetype)
WHERE   r.phonetype = t.phonetype;
然后您的查询变得更简单了:

SELECT DISTINCT ON (p.fullname, p.id)
       p.fullname, n.number, t.phonetype
FROM   phonenumber n 
JOIN   person      p ON p.id = n.personid
JOIN   phonetype   t ON t.id = n.phonetypeid
ORDER  BY p.fullname, p.id, t.rnk    -- add more columns to break ties (if any)