我正在使用postgresql而且我对它不熟悉。这段代码有效,但我想知道我是否可以用更简单的方式编写它。在这里,我加入了bar,在子查询中加入吧。我希望有一些像select * from bar group by baz using max(z)
select *
from foo f
join bar b on(f.baz=b.baz AND b.z in (select max(z) from bar group by baz))
where uid1 = 120
答案 0 :(得分:2)
只需使用<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/"
targetNamespace="http://tempuri.org/">
<xs:import namespace="http://schemas.xmlsoap.org/soap/envelope/"
schemaLocation="http://schemas.xmlsoap.org/soap/envelope/"/>
<xs:element name="Cancel_OrderLineReq">
<xs:complexType>
<xs:sequence>
<xs:element name="Data">
<xs:complexType>
<xs:sequence>
<xs:element name="Delivery" maxOccurs="unbounded" minOccurs="0">
<xs:complexType>
<xs:sequence>
<xs:element type="xs:int" name="Delivery_No"/>
<xs:element type="xs:string" name="Reason"/>
</xs:sequence>
</xs:complexType>
</xs:element>
</xs:sequence>
</xs:complexType>
</xs:element>
</xs:sequence>
</xs:complexType>
</xs:element>
</xs:schema>
:
distinct on
答案 1 :(得分:1)
@Gordon's answer几乎但不太正确。如果列可以是max(b.z)
,则ORDER BY b.z DESC
和NULL
之间会有细微差别。经常被忽视并引起很多头痛。
即使列b.z
已定义NOT NULL
,也可能会让您感到愤怒。外连接可以为列引入NULL
值。在这个简单的查询中不会有效,但可以在更复杂的查询中。
虽然汇总功能如min
,max
或count
忽略 NULL
值,但在ORDER BY
子句中使用相同的列时,必须以某种方式处理
在默认排序顺序NULL
值中排序最后。当排序顺序与DESC
相反时,NULL
值会先排序 。一定要保持一致。
因此,如果baz IS NULL
中的任何DISTINCT ON
值位于对等体集中,则从NULL
获得max(b.z)
行,其中您将从{{获得最大的非空值(如果有) 1}}。很可能不是你想要的。您可以使用 NULLS LAST
:
另外,在使用SELECT *
时,您不希望两次返回连接列baz
- 保证相同。 USING
子句派上用场,它只返回列一次。
所以:
SELECT DISTINCT ON (baz) *
FROM foo f
JOIN bar b USING (baz)
WHERE uid1 = 120 -- where from?
ORDER BY baz, b.z DESC NULLS LAST;
即使没有NULLS LAST
值, NULL
也不会受到伤害 - 除非您确实希望NULL
值占上风。
DISTINCT ON
的详细说明:
由于uid1
来自baz
(as commented),因此对于大型表格,此查询通常更快:
SELECT *
FROM foo f
JOIN (
SELECT DISTINCT ON (baz) *
FROM bar
WHERE uid1 = 120
ORDER BY baz, z DESC NULLS LAST
) b USING (baz);
根据表定义和数据分布,可能会有更快的查询技术:
答案 2 :(得分:0)
嗨,您可以进行以下查询,
SELECT * FROM foo f
INNER JOIN (SELECT baz, MAX(z) FROM bar GROUP BY baz) b
ON (f.baz = b.baz)
WHERE f.uid1 = 120;
只需使用MAX(z)连接条形并填充所需的值。 uid1必须来自foo表,因为f用作别名,如果没有更改为b.uid1