access a column aliases in the where clause in postgresql

只愿长相守 提交于 2021-02-05 12:08:11

问题


I understand that I may need to do grouping to accomplish this, but I can't quite get it. Postgresql 8.1

I am needing to limit my result set to Origination > 2017-01-01. Origination is set in line 11. It is being returned as a column in Excel and is a date.

Currently it returns results with data going back years and we don't need that.

select distribution_stop_information.customer_no,
distribution_line_items.item_number,
distribution_line_items.container_id,
distribution_line_items.item_description,
distribution_stop_information.customer_reference,
distribution_stop_information.bol_number, SUBSTRING(distribution_stop_information.bol_number,1,4) as ODDC,
SUBSTRING(distribution_stop_information.bol_number,9,4) as ODRT,
distribution_stop_information.branch_id,
distribution_stop_information.route_date,
(select count(innerDLI.item_number)-1 from distribution_line_items innerDLI where innerDLI.item_number = distribution_line_items.item_number) as RDLcount,
(select innerDLI.datetime_created from distribution_line_items innerDLI where innerDLI.item_number = distribution_line_items.item_number order by innerDLI.datetime_created asc limit 1) as Origination,
distribution_stop_information.route_code,
distribution_stop_information.stop_name,
distribution_stop_information.stop_address,
distribution_stop_information.stop_city,
distribution_stop_information.stop_state,
distribution_stop_information.stop_zip_postal_code,
distribution_stop_information.stop_signature,
CASE WHEN distribution_line_items.exception_code is not null
    THEN distribution_line_items.exception_code
    ELSE distribution_stop_information.stop_exception_code
    END as ExceptionCode,
distribution_stop_information.signature_file_name,
distribution_stop_information.sign_bitmap_file_exists,
ScanR.item_was_scanned as ScanR,
ScanL.item_was_scanned as ScanL,
ScanD.item_was_scanned as ScanD
from distribution_stop_information
inner join distribution_line_items on distribution_line_items.unique_id_no = distribution_stop_information.unique_id_no
left join distribution_item_scans ScanR on 
    ScanR.item_sequence_no = distribution_line_items.item_sequence_no
    and ScanR.stop_unique_id_no = distribution_stop_information.unique_id_no and ScanR.scan_type = 1
   left join distribution_item_scans ScanL on 
    ScanL.item_sequence_no = distribution_line_items.item_sequence_no
    and ScanL.stop_unique_id_no = distribution_stop_information.unique_id_no and ScanL.scan_type = 2
    and ScanL.scan_datetime between to_date(?, 'YYYY-MM-DD') and ( to_date(?, 'YYYY-MM-DD') + interval '1 day' )
left join distribution_item_scans ScanD on 
    ScanD.item_sequence_no = distribution_line_items.item_sequence_no
    and ScanD.stop_unique_id_no = distribution_stop_information.unique_id_no and ScanD.scan_type = 9
    and ScanD.scan_datetime between to_date(?, 'YYYY-MM-DD') and ( to_date(?, 'YYYY-MM-DD') + interval '1 day' ) 
where
distribution_stop_information.customer_no in ( '90202' )
and distribution_stop_information.route_date between ( to_date(?, 'YYYY-MM-DD') ) and ( to_date(?, 'YYYY-MM-DD') ) 
and distribution_line_items.datetime_created between ( to_date(?, 'YYYY-MM-DD') - interval '288 hours' ) and ( to_date(?, 'YYYY-MM-DD') + interval '12 hours' )

Update: I have changed the select to read like this, it seems to be working -- any thoughts on if this is the right way to do it? It is going to always be looking at just the past 180 days.

(select innerDLI.datetime_created from distribution_line_items innerDLI where innerDLI.item_number = distribution_line_items.item_number and innerDLI.datetime_created > to_date(?, 'YYYY-MM-DD') - interval '180 days'   order by innerDLI.datetime_created asc limit 1) as Origination,

回答1:


Here is how you did it - alias in the column name

select 
  -- etc etc 
  (select innerDLI.datetime_created from distribution_line_items innerDLI where innerDLI.item_number = distribution_line_items.item_number order by innerDLI.datetime_created asc limit 1) as Origination,
  -- etc etc
from distribution_stop_information
  -- etc etc

Here is how you can put it in the where, alias in the join

select 
  -- etc etc 
  Origination.datetime_created
  -- etc etc
from distribution_stop_information 
left join distribution_line_items AS Origination ON Origination.item_number = distribution_line_items.item_number
where Origination.datetime_created > to_date(?, 'YYYY-MM-DD') - interval '180 days'  
-- etc etc

There is nothing about this that is better than the solution you posted (the sql optimizer should result in the same plan) but it is "using an alias in the where clause"




回答2:


This moves it to the join, which should work for you.

select distribution_stop_information.customer_no,
distribution_line_items.item_number,
distribution_line_items.container_id,
distribution_line_items.item_description,
distribution_stop_information.customer_reference,
distribution_stop_information.bol_number, SUBSTRING(distribution_stop_information.bol_number,1,4) as ODDC,
SUBSTRING(distribution_stop_information.bol_number,9,4) as ODRT,
distribution_stop_information.branch_id,
distribution_stop_information.route_date,
(select count(innerDLI.item_number)-1 from distribution_line_items innerDLI where innerDLI.item_number = distribution_line_items.item_number) as RDLcount,
o.Origination,
distribution_stop_information.route_code,
distribution_stop_information.stop_name,
distribution_stop_information.stop_address,
distribution_stop_information.stop_city,
distribution_stop_information.stop_state,
distribution_stop_information.stop_zip_postal_code,
distribution_stop_information.stop_signature,
CASE WHEN distribution_line_items.exception_code is not null
    THEN distribution_line_items.exception_code
    ELSE distribution_stop_information.stop_exception_code
    END as ExceptionCode,
distribution_stop_information.signature_file_name,
distribution_stop_information.sign_bitmap_file_exists,
ScanR.item_was_scanned as ScanR,
ScanL.item_was_scanned as ScanL,
ScanD.item_was_scanned as ScanD
from distribution_stop_information
inner join distribution_line_items on distribution_line_items.unique_id_no = distribution_stop_information.unique_id_no
left join distribution_item_scans ScanR on 
    ScanR.item_sequence_no = distribution_line_items.item_sequence_no
    and ScanR.stop_unique_id_no = distribution_stop_information.unique_id_no and ScanR.scan_type = 1
   left join distribution_item_scans ScanL on 
    ScanL.item_sequence_no = distribution_line_items.item_sequence_no
    and ScanL.stop_unique_id_no = distribution_stop_information.unique_id_no and ScanL.scan_type = 2
    and ScanL.scan_datetime between to_date(?, 'YYYY-MM-DD') and ( to_date(?, 'YYYY-MM-DD') + interval '1 day' )
left join distribution_item_scans ScanD on 
    ScanD.item_sequence_no = distribution_line_items.item_sequence_no
    and ScanD.stop_unique_id_no = distribution_stop_information.unique_id_no and ScanD.scan_type = 9
    and ScanD.scan_datetime between to_date(?, 'YYYY-MM-DD') and ( to_date(?, 'YYYY-MM-DD') + interval '1 day' ) 
inner join (select innerDLI.datetime_created as Origination, innerDLI.item_number from distribution_line_items innerDLI where innerDLI.item_number = distribution_line_items.item_number order by innerDLI.datetime_created asc limit 1) o
on distribution_line_items.item_number = o.item_number
where
distribution_stop_information.customer_no in ( '90202' )
and distribution_stop_information.route_date between ( to_date(?, 'YYYY-MM-DD') ) and ( to_date(?, 'YYYY-MM-DD') ) 
and distribution_line_items.datetime_created between ( to_date(?, 'YYYY-MM-DD') - interval '288 hours' ) and ( to_date(?, 'YYYY-MM-DD') + interval '12 hours' )
and o.Origination > '2017-01-01'


来源:https://stackoverflow.com/questions/42935760/access-a-column-aliases-in-the-where-clause-in-postgresql

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!