Ale*_*vić 2 postgresql group-by
我在 MySql 中有这个视图查询,它可以工作
SELECT s.id AS id,
s.customer_id AS customer_id,
s.shipment_status_id AS shipment_status_id,
ss.name AS shipment_status_name,
s.ship_from_date AS ship_from_date,
s.ship_to_company AS ship_to_company,
s.ship_from_company AS ship_from_company,
s.ship_to_address1 AS ship_to_address1,
s.ship_to_address2 AS ship_to_address2,
s.ship_to_postal_code AS ship_to_postal_code,
s.ship_to_city AS ship_to_city,
c.country AS country,
p.tracking_numbers AS tracking_numbers,
s.quote_service_name AS quote_service_name,
s.quote_total_charge AS quote_total_charge,
p.weight AS weight,
p.insurance_amount AS insurance_amount,
p.cod_amount AS cod_amount,
z.fedex AS ZONE,
s_p.code AS state_province_code,
s_p.zone AS state_province_zone,
ss.name AS status_name,
i.total AS total,
cust.first_name AS customer_first_name,
cust.last_name AS customer_last_name,
(CASE
WHEN (s.additional_services_saturday_delivery = 1) THEN 'Yes'
END) AS saturday_delivery,
(CASE
WHEN (s.additional_services_hold_for_pickap = 1) THEN 'Yes'
END) AS hold_for_pickap,
(CASE
WHEN (s.ship_to_residential = 1) THEN 'Yes'
END) AS ship_to_residential,
(CASE
WHEN (s.additional_services_signature_required = 1) THEN 'Yes'
END) AS signature_required
FROM (((((((shipments s
LEFT JOIN shipment_package_group_data p on((s.id = p.shipment_id)))
LEFT JOIN country c on((s.ship_to_country_id = c.id)))
LEFT JOIN invoice i on((s.invoice_id = i.id)))
LEFT JOIN state_province s_p on((s.ship_to_state = s_p.id)))
LEFT JOIN shipment_statuses ss on((s.shipment_status_id = ss.id)))
LEFT JOIN zones z on((s.zone_id = z.id)))
JOIN customer cust on((s.customer_id = cust.id)))
GROUP BY s.id
Run Code Online (Sandbox Code Playgroud)
但是当我尝试将其转换为 PostgreSQL 视图时:
SELECT s.id AS id,
s.customer_id AS customer_id,
s.shipment_status_id AS shipment_status_id,
ss.name AS shipment_status_name,
s.ship_from_date AS ship_from_date,
s.ship_to_company AS ship_to_company,
s.ship_from_company AS ship_from_company,
s.ship_to_address1 AS ship_to_address1,
s.ship_to_address2 AS ship_to_address2,
s.ship_to_postal_code AS ship_to_postal_code,
s.ship_to_city AS ship_to_city,
c.country AS country,
p.tracking_numbers AS tracking_numbers,
s.quote_service_name AS quote_service_name,
s.quote_total_charge AS quote_total_charge,
p.weight AS weight,
p.insurance_amount AS insurance_amount,
p.cod_amount AS cod_amount,
z.fedex AS ZONE,
s_p.code AS state_province_code,
s_p.zone AS state_province_zone,
ss.name AS status_name,
i.total AS total,
cust.first_name AS customer_first_name,
cust.last_name AS customer_last_name,
(CASE
WHEN (s.additional_services_saturday_delivery = 1) THEN 'Yes'
END) AS saturday_delivery,
(CASE
WHEN (s.additional_services_hold_for_pickap = 1) THEN 'Yes'
END) AS hold_for_pickap,
(CASE
WHEN (s.ship_to_residential = 1) THEN 'Yes'
END) AS ship_to_residential,
(CASE
WHEN (s.additional_services_signature_required = 1) THEN 'Yes'
END) AS signature_required
FROM (shipments s
LEFT JOIN shipment_package_group_data p on(s.id::INT = p.shipment_id)
LEFT JOIN country c on((s.ship_to_country_id = c.id))
LEFT JOIN invoice i on((s.invoice_id = i.id))
LEFT JOIN state_province s_p on((s.ship_to_state::INT = s_p.id))
LEFT JOIN shipment_statuses ss on((s.shipment_status_id = ss.id))
LEFT JOIN zones z on((s.zone_id = z.id))
JOIN customer cust on((s.customer_id = cust.id)))
GROUP BY s.id
Run Code Online (Sandbox Code Playgroud)
PostgreSQL 抱怨以下内容:
[Err] ERROR: column "ss.name" must appear in the GROUP BY clause or be used in an aggregate function
LINE 4: ss.name AS shipment_status_name,
^
Run Code Online (Sandbox Code Playgroud)
TL;DR MySQL 忽略 SQL 标准并允许您的原始查询返回不确定的结果。Postgres 不允许你这样做。您需要正确定义您期望的结果。
您可以在此 SO 帖子中看到 MySQL 所依赖的行为的解释。当您将查询转换为 Postgres 时,您需要填写原始查询的作者忽略的内容:有一个GROUP BY s.id
,因此对于每个s.id
分组依据,ss.name
必须返回哪个?可能有几个不同的ss.name
值,数据库应该如何决定给你哪一个?请注意,这ss.name
不是此查询中唯一有问题的列,您正在选择的所有非聚合列可能需要在此查询中正确处理。
最终,您将需要使用以下组合:
GROUP BY
完全摆脱并简单地返回所有结果GROUP BY
您正在使用的所有非聚合列SELECT
,例如GROUP BY s.id, s.customer_id, s.shipment_status_id, ...
SELECT ... DISTINCT ON ... ORDER BY
要告诉Postgres的,你只在乎曾经收到一个单一的s.customer_id
,s.shipment_status_id
,ss.name
,等等。对于每个s.id
你是GROUP
由荷兰国际集团。该ORDER BY
会指示的Postgres如何决定哪些每一个s.customer_id
等返回。...而且可能还有一些我忽略的解决方法,但这应该可以让您朝着正确的方向开始。
归档时间: |
|
查看次数: |
358 次 |
最近记录: |