2
SELECT DISTINCT a.s_id, select2Result.s_id, select2Result."mNrPhone", 
       select2Result."dNrPhone" 
FROM "Table1" AS a INNER JOIN
    (
    SELECT b.s_id, c."mNrPhone", c."dNrPhone" FROM "Table2" AS b, "Table3" AS c  
    WHERE b.a_id = 1001 AND b.s_id = c.s_id
    ORDER BY b.last_name) AS select2Result
ON a.a_id = select2Result.student_id
WHERE a.k_id = 11211 

它返回:

1001;1001;"";""
1002;1002;"";""
1002;1002;"2342342232123";"2342342"
1003;1003;"";""
1004;1004;"";""

1002 值重复了两次,但这不应该是因为我使用过DISTINCT并且没有其他表的 id 重复两次。

4

3 回答 3

3

您可以像这样使用DISTINCT ON

   SELECT DISTINCT ON (a.s_id) 
          a.s_id, select2Result.s_id, select2Result."mNrPhone", 
          select2Result."dNrPhone"
   ...

但是就像其他人告诉你的那样,“重复记录”确实不同。

于 2012-08-10T12:35:30.180 回答
2

限定符 DISTINCT 适用于整行,而不适用于选择列表中的第一列。由于带有 的两行的第 3 列和第 4 列(mNrPhonedNrPhone)不同s_id = 1002,因此 DBMS 正确列出了这两行。如果您只想s_id = 1002显示一次,则必须以不同的方式编写查询,并且您必须决定要显示哪些辅助数据。

顺便说一句,强烈建议您始终在所有查询和子查询中使用显式 JOIN 表示法(在 SQL-92 中引入)。不要使用旧的隐式连接表示法(这是 SQL-86 或 SQL-89 中可用的全部),尤其不要混合使用显式和隐式连接表示法(您的子查询使用隐式连接,但主查询使用显式连接)。您需要了解旧的表示法,以便理解旧的查询。您应该用新的符号编写新的查询。

于 2012-08-10T12:13:02.987 回答
1

首先,显示的查询根本不起作用,子查询student_id中缺少。稍后在 JOIN 中使用它。

更有趣的是:

从一组中选择某一行DISTINCT

DISTINCTDISTINCT ON通过根据要区分的列集对所有行进行排序来返回不同的值,然后从每个集合中选择第一行。它按常规的所有行排序DISTINCT,仅按指定的行排序DISTINCT ON。这是从一组中挑选某些行而不是其他行的机会。

例如,如果您在示例中更喜欢带有非空“mNrPhone”的行:

SELECT DISTINCT ON (a.s_id)   -- sure you didn't want a.a_id?
      ,a.s_id AS a_s_id  -- use aliases to avoid dupe name
      ,s.s_id AS s_s_id
      ,s."mNrPhone"
      ,s."dNrPhone" 
FROM  "Table1" a
JOIN  (
    SELECT b.s_id, c."mNrPhone", c."dNrPhone", ??.student_id  -- misssing!
    FROM  "Table2" b
    JOIN  "Table3" c USING (s_id)
    WHERE  b.a_id = 1001 
    --    ORDER  BY b.last_name  -- pointless, DISTINCT will re-order
     ) s ON a.a_id = s.student_id
WHERE  a.k_id = 11211
ORDER  BY a.s_id -- first col must agree with DISTINCT ON, could add DESC though
         ,("mNrPhone" <> '') DESC -- non-empty first

ORDER BYDISTINCT不能在同一查询级别上不同意。为了解决这个问题,您可以GROUP BY改用或将整个查询放在子查询中并在其上运行另一个SELECT查询ORDER BY

ORDER BY您在子查询中的内容现在无效。

在这种特殊情况下,如果 - 看起来 - 欺骗仅来自子查询(您必须验证),您可以改为:

SELECT a.a_id, s.s_id, s."mNrPhone", s."dNrPhone" -- picking a.a_id over s_id
FROM  "Table1" a
JOIN  (
    SELECT DISTINCT ON (b.s_id)
          ,b.s_id, c."mNrPhone", c."dNrPhone", ??.student_id  -- misssing!
    FROM  "Table2" b
    JOIN  "Table3" c USING (s_id)
    WHERE  b.a_id = 1001 
    ORDER  BY b.s_id, (c."mNrPhone" <> '') DESC -- pick non-empty first
     ) s ON a.a_id = s.student_id
WHERE  a.k_id = 11211
ORDER  BY a.a_id  -- now you can ORDER BY freely
于 2012-08-10T15:13:25.487 回答