Sql 连接一对多并检索单个结果

Sql 连接一对多并检索单个结果,sql,postgresql,select,join,one-to-many,Sql,Postgresql,Select,Join,One To Many,我有两个表,在PostgreSQL中,如果有关系的话,有一对多关系。我需要加入它们,这样对于每个“一”,我只能从“多”表中得到一个结果。不仅如此,我还需要从“许多”表中挑出具体的结果 表A ID |姓名|日期|更多颜色。。。。 约翰2012-01-10。。。。 2 |丽莎| 2012-01-10 |。。。。 3 | ANNY | 2012-01-10 |。。。。 詹姆斯2012-01-10。。。。 ... 表B ID |代码1 |代码2 |排序 1 | 04020 | 85003

我有两个表,在PostgreSQL中,如果有关系的话,有一对多关系。我需要加入它们,这样对于每个“一”,我只能从“多”表中得到一个结果。不仅如此,我还需要从“许多”表中挑出具体的结果

表A ID |姓名|日期|更多颜色。。。。 约翰2012-01-10。。。。 2 |丽莎| 2012-01-10 |。。。。 3 | ANNY | 2012-01-10 |。。。。 詹姆斯2012-01-10。。。。 ... 表B ID |代码1 |代码2 |排序 1 | 04020 | 85003 | 1 1 | 04030 | 85002 | 4 2 | 81000 | 80703 | 1 3 | 87010 | 80102 | 4 3 | 87010 | 84701 | 5 4 | 04810 | 85003 | 1 4 | 04030 | 85002 | 4 4 | 04020 | 85003 | 1 ... 查询结果 ID |姓名|日期|代码1 |代码2 1 |约翰| 2012-01-10 | 04020 | 85003 2 |丽莎| 2012-01-10 | 81000 | 80703 3 | ANNY | 2012-01-10 | 87010 | 80102 4 |詹姆斯| 2012-01-10 | 04810 | 85003 ... 表_B中的排序列实际上是代码2中重新排序的最后一个字符。代码2可以以1-9结尾,但3比5、7、4、2、1、0、6、8、9更重要,因此3-->1、5-->2、7-->3等等


我面临的问题是,我需要表B中的行,其中sort是最小的数字。在某些情况下,有多个最低的情况(请参见表B中的ID=4),那么选择ID最低的行并不重要,只是该ID有一个结果。

PostgreSQL支持。试试这个

SELECT d.ID, d.NAME, d.DATE, d.CODE1, d.CODE2
FROM
(
  SELECT  a.ID, a.NAME, a.DATE,
          b.CODE1, b.CODE2,
          ROW_NUMBER() OVER(PARTITION BY a.ID ORDER BY b.SORT ASC, b.CODE2 DESC) AS ROWNUM
  FROM    TableA a
          INNER JOIN TableB b
            ON a.ID = b.ID
) d
WHERE d.RowNum = 1

下面是我在SQL Server上要做的事情

SELECT a.ID,
    a.NAME,
    a.DATE,
    b.CODE1,
    b.CODE2
FROM TABLE_A a
JOIN TABLE_B b
    on a.ID = b.ID
WHERE b.SORT = (SELECT MIN(SORT) 
    FROM TABLE_B
    WHERE ID = b.ID)

PostgreSQL的
上的独特功能更简单、更短、更快:

SELECT DISTINCT ON (a.id)
       a.id, a.name, a.date, b.code1, b.code2
FROM   table_a a
LEFT   JOIN table_b b USING (id)
ORDER  BY a.id, b.sort
详细信息、说明、基准和中的链接。
我使用
左联接
,这样就不会删除
表a
中没有任何匹配行的行

旁注:

虽然在PostgreSQL中是允许的,但使用
date
作为列名是不明智的。它是每个SQL标准中的一个名称,也是PsotgreSQL中的一个类型名称


命名ID列
ID
也是一种反模式。没有描述性,也没有帮助。一种(许多)可能的命名约定是以主键所在的表命名:
table\u a\u id
。引用它的外键的名称相同(如果没有其他自然名称优先)。

谢谢,但这给了我相同的结果,就像我将表_B中的所有内容都合并到表_A中,这是多对一的结果。@user1678791因为您添加了
postgresql
标记,所以我使用
窗口函数
Eureka更新了答案!非常感谢,这就是我问题的答案+1对于SQLFiddle演示,简直太棒了。fiddle不再给出正确的结果。欢迎使用StackOverflow!感谢您展示数据并撰写清晰的问题。不过,下一次,如果您以
CREATE TABLE
语句和
INSERT
COPY
语句的形式显示数据以加载数据,您将使希望帮助您的人的生活变得更轻松。这样,人们可以在发布前轻松测试候选答案,以确保他们没有语法错误,并得到您想要的结果。谢谢您的评论。从现在开始我会这样做。谢谢,这个解决方案也很有效。对于这个例子,列的命名完全是出于描述性的原因。@thorgilsv:我理解。这个版本应该快一点。你可以用它来测试。
SELECT DISTINCT ON (a.id)
       a.id, a.name, a.date, b.code1, b.code2
FROM   table_a a
LEFT   JOIN table_b b USING (id)
ORDER  BY a.id, b.sort