在MySQL中我使用了很多看起来像这样的结构:
LEFT JOIN(
SELECT field_one, field_two, field_three FROM (
SELECT field_one, field_two, field_three FROM table_one
ORDER BY field_three
) o GROUP BY field_one
) abc ON cur_table.some_field = abc.field_one
我使用它,因为它帮助我实现了一个常规任务 - 在分组之前订购一些数据。现在我想知道如何将这个SQL结构从MySQL迁移到 SQLite 和 PostgreSQL 。
答案 0 :(得分:2)
我怀疑你的查询的目的是使用MySQL怪癖为未聚合的列选择任意行,这些列也未在现有GROUP BY
子句中列出(违反SQL标准并且大多数其他RDBMS都不支持。通过在子查询中排序,你可以让MySQL选择每个gropup最小field_three
的行,所以我假设你想要:
每个field_three
的最小field_one
,以及来自同一行的field_two
。
你的原始查询不在Postgres中工作,这符合SQL标准。如果SELECT
具有GROUP BY
子句,则必须列出或汇总所有输出列。考虑:
一个可能的标准SQL 解决方案将在子查询中使用窗口函数row_number()
:
SELECT field_one, field_two, field_three
FROM (
SELECT field_one, field_two, field_three
, row_number() OVER(PARTITION BY field_one ORDER BY field_three) rn
FROM table_one
) sub
WHERE sub.rn = 1
适用于Postgres,但不适用于不支持窗口功能的SQLite或MySQL。
此查询适用于所有三个RDBMS(以及几乎其他任何地方),但在field_three
中需要唯一的最大值(如果每field_three
存在最大field_one
个关联,则返回多行})。
SELECT t1.*
FROM table_one t1
LEFT JOIN table_one t2 ON t1.field_one = t2.field_one
AND t1.field_three < t2.field_three
WHERE t2.field_one IS NULL
如果您有任何唯一(一组)列,您可以解决关系,但它不实用。相关:
(除了支持所有标准的SQL解决方案)Postgres还具有强大的DISTINCT ON
(标准DISTINCT
的扩展,但不是反对标准,如MySQL和SQLite怪癖):
SELECT DISTINCT ON (field_one)
field_one, field_two, field_three
FROM table_one
ORDER BY field_one, field_three
您可以通过向ORDER BY
添加更多列来解决关联问题。详细说明:
...与MySQL有类似的怪癖(违反了SQL标准)。 From the release notes:
表格的查询:&#34; SELECT max(x),y FROM table&#34;返回包含最大x值的同一行上的y值。
所以:
SELECT field_one, field_two, max(field_three) AS field_three
FROM table_one
GROUP BY field_one
field_two
取自max(field_three)
行。相关:
加入并加入条件工作无处不在:
LEFT JOIN (SELECT ...) abc ON cur_table.some_field = abc.field_one