首先,显示的查询根本不起作用,子查询student_id
中缺少。稍后在 JOIN 中使用它。
更有趣的是:
从一组中选择某一行DISTINCT
DISTINCT
并DISTINCT 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 BY
DISTINCT
不能在同一查询级别上不同意。为了解决这个问题,您可以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