Home > OS >  Between DATE and TODAY
Between DATE and TODAY

Time:11-17

On Oracle SQL Developer I am trying to use this code below as base. However, with this code all the possible data are shown, but I would like to filter the results

WHERE oh.ship_by_date BETWEEN '01/01/2021' AND current date

(In system DATE is shown as dd/mm/yyyy)

I tried to put this filter but I do not understand why the results are still coming out with all ship by dates, hence are not filtered. Where would I have to put the filter, and how could I write it correctly? Thank you so much for your help.

select  
  q1.order_id, q1.status,  q1.ship_by_date, q1.shipped_date,
  count(q1.order_id) lines, sum(q1.qty_ordered) qty, 
  q1.user_def_num_4, q1.user_def_note_2, q1.name, q1.order_type, q1.seller_name, 
  sum(q1.qty_shipped), 
  q1.work_group, q1.creation_Date
from
(
  SELECT 
    OH.ORDER_ID, OH.STATUS, TO_CHAR( OH.SHIP_BY_DATE, 'YYYY-MM-DD')  ship_by_date,
    TO_CHAR(OH.SHIPPED_DATE,'YYYY-MM-DD') shipped_date, ol.QTY_ORDERED, 
    oh.user_def_num_4, oh.user_def_note_2, oh.name, oh.order_type, ol.qty_shipped,
    oh.seller_name, oh.creation_date, oh.work_group
  FROM V_ORDER_HEADER Oh
  left JOIN v_order_line ol on oh.order_id = ol.order_id
  union all
  (
    SELECT 
      OH.ORDER_ID, OH.STATUS,  TO_CHAR( OH.SHIP_BY_DATE, 'YYYY-MM-DD')  ship_by_date,
      TO_CHAR(OH.SHIPPED_DATE,'YYYY-MM-DD') shipped_date, ol.QTY_ORDERED, 
      oh.user_def_num_4, oh.user_def_note_2, oh.name, oh.order_type, ol.qty_shipped,
      oh.seller_name, oh.creation_date, oh.work_group
    FROM V_ORDER_HEADER_archive Oh
    left JOIN v_order_line_archive ol on oh.order_id = ol.order_id
    union
    SELECT 
      OH.ORDER_ID, OH.STATUS, TO_CHAR( OH.SHIP_BY_DATE, 'YYYY-MM-DD')  ship_by_date,
      TO_CHAR(OH.SHIPPED_DATE,'YYYY-MM-DD') shipped_date, ol.QTY_ORDERED, 
      oh.user_def_num_4, oh.user_def_note_2, oh.name, oh.order_type, ol.qty_shipped,
      oh.seller_name, oh.creation_date, oh.work_group
    FROM V_ORDER_HEADER_archive_2 Oh
    left JOIN v_order_line_archive ol on oh.order_id = ol.order_id
  )
) q1
group by 
  q1.order_id, q1.status, q1.ship_by_date,  q1.shipped_date, 
  q1.NAME, q1.order_type, q1.user_def_num_4, q1.user_def_note_2, q1.seller_name,
  q1.work_group, q1.creation_Date

Thank you.

CodePudding user response:

There are two ways that immediately come to mind. In both cases i would recommend attempting to cast your ship_by_date as a datetime and then comparing against your (hardcoded?) 2021 date and current date.

E.g:

WHERE CAST(oh.ship_by_date AS datetime) 
BETWEEN '2021-01-01 00:00:00.000' AND GETDATE()

Or

WHERE CAST(oh.ship_by_date AS datetime) > '2021-01-01 00:00:00.000' 
and CAST(oh.ship_by_date AS datetime) < GETDATE()

EDIT - I just realised you are also turning your oh.ship_by_date to a CHAR using TO_CHAR in your selects. Try taking that part out too. E.g.

select  q1.order_id, q1.status ,  q1.ship_by_date, q1.shipped_date,
count(q1.order_id) lines, sum(q1.qty_ordered) qty, q1.user_def_num_4, q1.user_def_note_2, q1.name, q1.order_type, q1.seller_name, sum(q1.qty_shipped), q1.work_group, q1.creation_Date
from
(SELECT OH.ORDER_ID, OH.STATUS, OH.SHIP_BY_DATE, TO_CHAR(OH.SHIPPED_DATE,'YYYY-MM-DD') shipped_date, ol.QTY_ORDERED, 
oh.user_def_num_4, oh.user_def_note_2, oh.name, oh.order_type, ol.qty_shipped, oh.seller_name, oh.creation_date, oh.work_group
FROM V_ORDER_HEADER Oh
left JOIN v_order_line ol on oh.order_id = ol.order_id
--where oh.order_id = '0082693218') */
union all
(SELECT OH.ORDER_ID, OH.STATUS, OH.SHIP_BY_DATE, TO_CHAR(OH.SHIPPED_DATE,'YYYY-MM-DD') shipped_date, ol.QTY_ORDERED, 
oh.user_def_num_4, oh.user_def_note_2, oh.name, oh.order_type, ol.qty_shipped, oh.seller_name, oh.creation_date, oh.work_group
FROM V_ORDER_HEADER_archive Oh
left JOIN v_order_line_archive ol on oh.order_id = ol.order_id
union
SELECT OH.ORDER_ID, OH.STATUS, OH.SHIP_BY_DATE, TO_CHAR(OH.SHIPPED_DATE,'YYYY-MM-DD') shipped_date, ol.QTY_ORDERED, 
oh.user_def_num_4, oh.user_def_note_2, oh.name, oh.order_type, ol.qty_shipped, oh.seller_name, oh.creation_date, oh.work_group
FROM V_ORDER_HEADER_archive_2 Oh
left JOIN v_order_line_archive ol on oh.order_id = ol.order_id))
--where oh.order_id = '0082693218') */
q1

WHERE CAST(oh.ship_by_date AS datetime) 
BETWEEN '2021-01-01 00:00:00.000' AND GETDATE()

group by q1.order_id, q1.status, q1.ship_by_date,  q1.shipped_date, 
q1.NAME, q1.order_type, q1.user_def_num_4, q1.user_def_note_2, q1.seller_name, q1.work_group, q1.creation_Date

CodePudding user response:

You can place the following WHERE clause with every query part, i.e. after each LEFT JOIN clause.

WHERE oh.ship_by_date >= DATE '2021-01-01' AND oh.ship_by_date < TRUNC(SYSDATE)   1

(The 1 is short for INTERVAL '1' DAY by the way.)

The other option would be to place the following WHERE clause after unioning all the tables (i.e. after ) q1.

WHERE q1.ship_by_date >= DATE '2021-01-01' AND q1.ship_by_date < TRUNC(SYSDATE)   1

But this would probably be much slower, because you are dealing with all the data first rather than just with the date range you are interested in, and then only in the very end you apply that date range limit. So, while this alternative may be considered more readable and better maintainable, it is probably still a bad idea.

Then, you are using a constant 2021-01-01 here. Will this be still the same value when you run the query next year? If you want the current year instead, you can use

WHERE oh.ship_by_date >= TRUNC(SYSDATE, 'YEAR') AND oh.ship_by_date < TRUNC(SYSDATE)   1

At last a remark on your data: You are dealing with history tables here. The more current entries are in V_ORDER_HEADER and V_ORDER_LINE. The older rows have been moved to V_ORDER_HEADER_ARCHIVE, V_ORDER_HEADER_ARCHIVE_2 and V_ORDER_LINE_ARCHIVE. From the names all these are views, not tables, so I don't know what magic happens behind the scenes here. Generally it is often a better idea to work with partitioned tables, so you work with only one table instead of with a current table and a history table in your query and the DBMS then accesses the partitions it needs to fulfill the task, which is usually only the current partition(s), while old partitions are seldom accessed. And old data can be removed much quicker by merely dropping old partitions.

  • Related