Странное поведение по запросу Postgresql - PullRequest
0 голосов
/ 12 октября 2018

Мы создали представление в Postgres, и я получаю странный результат.

Просмотр имени: event_puchase_product_overview

Когда я пытаюсь получить записи с *, я получаю правильный результат.но когда я пытаюсь получить конкретные поля, я получаю неправильные значения.

Я надеюсь, что скриншоты, представленные здесь, могут хорошо объяснить проблему.

select * 
from event_purchase_product_overview 
where id = 15065;

img

select id, departure_id 
from event_puchase_product_overview 
where id = 15065;

img

ПОСМОТРЕТЬ ОПРЕДЕЛЕНИЕ:

CREATE OR REPLACE VIEW public.event_puchase_product_overview AS 
 SELECT row_number() OVER () AS id,
    e.id AS departure_id,
    e.type AS event_type,
    e.name,
    p.id AS product_id,
    pc.name AS product_type,
    product_date.attribute AS option,
    p.upcomming_date AS supply_date,
    pr.date_end AS bid_deadline,
        CASE
            WHEN (pt.categ_id IN ( SELECT unnest(tt.category_ids) AS unnest
               FROM ( SELECT string_to_array(btrim(ir_config_parameter.value, '[]'::text), ', '::text)::integer[] AS category_ids
                       FROM ir_config_parameter
                      WHERE ir_config_parameter.key::text = 'trip_product_flight.product_category_hotel'::text) tt)) THEN e.maximum_rooms
            WHEN (pt.categ_id IN ( SELECT unnest(tt.category_ids) AS unnest
               FROM ( SELECT string_to_array(btrim(ir_config_parameter.value, '[]'::text), ', '::text)::integer[] AS category_ids
                       FROM ir_config_parameter
                      WHERE ir_config_parameter.key::text = 'trip_product_flight.product_category_flight'::text) tt)) THEN e.maximum_seats
            WHEN (pt.categ_id IN ( SELECT unnest(tt.category_ids) AS unnest
               FROM ( SELECT string_to_array(btrim(ir_config_parameter.value, '[]'::text), ', '::text)::integer[] AS category_ids
                       FROM ir_config_parameter
                      WHERE ir_config_parameter.key::text = 'trip_product_flight.product_category_bike'::text) tt)) THEN e.maximum_bikes
            ELSE e.maximum_seats
        END AS departure_qty,
        CASE
            WHEN now()::date > pr.date_end AND po.state::text = 'draft'::text THEN true
            ELSE false
        END AS is_deadline,
    pl.product_qty::integer AS purchased_qty,
    pl.comments,
    pl.price_unit AS unit_price,
    rp.id AS supplier,
    po.id AS po_ref,
    po.state AS po_state,
    po.date_order AS po_date,
    po.user_id AS operator,
    pl.po_state_line AS line_status
   FROM event_event e
     LEFT JOIN product_product p ON p.related_departure = e.id
     LEFT JOIN product_template pt ON pt.id = p.product_tmpl_id
     LEFT JOIN product_category pc ON pc.id = pt.categ_id
     LEFT JOIN purchase_order_line pl ON pl.product_id = p.id
     LEFT JOIN purchase_order po ON po.id = pl.order_id
     LEFT JOIN purchase_order_purchase_requisition_rel prr ON prr.purchase_order_id = po.id
     LEFT JOIN purchase_requisition pr ON pr.id = prr.purchase_requisition_id
     LEFT JOIN res_partner rp ON rp.id = po.partner_id
     LEFT JOIN ( SELECT p_1.id AS product_id,
            pav.name AS attribute
           FROM product_product p_1
             LEFT JOIN product_attribute_value_product_product_rel pa ON pa.prod_id = p_1.id
             LEFT JOIN product_attribute_value pav ON pav.id = pa.att_id
             LEFT JOIN product_attribute pat ON pat.id = pav.attribute_id
          WHERE pat.name::text <> ALL (ARRAY['Date'::character varying, 'Departure'::character varying]::text[])) product_date ON product_date.product_id = p.id
  WHERE (p.id IN ( SELECT DISTINCT mrp_bom_line.product_id
           FROM mrp_bom_line)) AND p.active
  ORDER BY e.id, pt.categ_id, p.id;

Ответы [ 2 ]

0 голосов
/ 12 октября 2018

Скорее всего, план выполнения вашего запроса зависит от выбранных вами столбцов.Сравните планы выполнения!

Ваш id создан с использованием оконной функции row_number.Теперь оконные функции выполняются перед предложением ORDER BY, поэтому порядок будет зависеть от плана выполнения и, следовательно, от выбранных вами столбцов.

Использование row_number без явного упорядоченияНе имеет никакого смысла.

Чтобы это исправить, не используйте

row_number() OVER ()

, но

row_number() OVER (ORDER BY e.id, pt.categ_id, p.id)

, чтобы иметь надежный заказ.

Кроме того, в конце следует опустить предложение ORDER BY.

0 голосов
/ 12 октября 2018

Если я добавлю новый event_event или новый product_product, я получу новое определение row_number в моем представлении, тогда идентификатор столбца моего представления будет нестабильным.

по крайней мере вы не можете использовать row_number какИдентификатор представления,

Если вы настаиваете на использовании row_number, вы можете использовать Order By "DATE ​​создания", таким образом, все новые записи будут последними строками в представлении, и это не изменит соответствие междуID (row_number) и другие столбцы.

Надеюсь, это поможет!

...