OR for two different columns - sql

I am trying to select specific rows from an Oracle DB.
The table has the following structure:
Order
Date
Status
1
01.01.2018
10
2
01.01.2018
15
I would like to extract all rows where
Status = < 85 or
the order date is in this week
Unfortunately, column Status is declared as a text column.
How would you build a SQL to extract these specific rows?

Hmmm . . . I don't know what you mean by "this week". Perhaps:
where status <= '85' or
orderdate >= trunc(sysdate, 'IW')
This does a string comparison on the status, so '9' would not be matched, and uses the ISO definition of week for the current week.
If you want a numeric comparison for status, then:
where to_number(status) <= 85 or
orderdate >= trunc(sysdate, 'IW')

Maybe try the CAST function like
select* from yourtable where cast(Status as INT) <=85 AND
to_char(to_date(date,'MM/DD/YYYY'),'WW')=to_char(to_date(sysdate,'MM/DD/YYYY'),'WW')

Related

Hive + Pass previous day date to like clause

Am trying to fetch records from hive table based on the previous date.
Example: If table is as follows
CustomerVisit table
ID NAME VISIT_DATE
------------------
01 Harish 2018-02-31
03 Satish 2017-02-13
04 Shiva 2018-03-04
Now i need to fetch all records that have visit_date = 2018-03-04 (i.e today's date -1).
Expected Query something like:
select ID, Name from CustomerVisit where
visit_date like concat((select date_sub(current_date, 1)),'%')
I have tried following
select current_date; - Gives current date
select date_sub(current_date, 1) - Gives previous date
select concat(tab1.date1,'%') from
(select date_sub(current_date, 1) as date1) as tab1; -- Gives the previous date appended with % which i need to use in like
but when i use the above as sub-query like below it fails with
select tab2.id, (select concat(tab1.date1,'%') as pattern from
(select date_sub(current_date, 1) as date1) as tab1) from CustomerVisit as tab2 limit 1;
FAILED: ParseException line 1:0 cannot recognize input near 'seelct' 'current_date' ''
How to write query to get results for previous date?
You don't need a LIKE clause. Just select using an equal to (=)
select ID, Name from CustomerVisit where
visit_date = date_sub(current_date, 1);

UPDATE month and year to current but leave day

I have situation in Oracle DB where I need to UPDATE every month some dates in table following this condition:
1) If date in table like '03.06.2017' UPDATE to '03.11.2017'
2) If date in table like '29.06.2016' UPDATE to '29.11.2017'
2) If date in table like '15.02.2016' UPDATE to '15.11.2017'
So basically always UPDATE part of date(month, year) to current month/year but always leave day as it is.
Edit:
It will be all months from 1-12 not only June. I need to do something like this... UPDATE table SET date = xx.(month from sysdate).(year from sysdate) WHERE... xx (day) leave as it is in DB.
Br.
You can use MONTHS_BETWEEN to determine how many months you need to add and then use the ADD_MONTHS function:
SQL Fiddle
Oracle 11g R2 Schema Setup:
CREATE TABLE dates ( value ) AS
SELECT DATE '2017-06-03' FROM DUAL UNION ALL
SELECT DATE '2016-06-29' FROM DUAL UNION ALL
SELECT DATE '2016-02-15' FROM DUAL UNION ALL
SELECT DATE '2016-03-31' FROM DUAL;
Update:
UPDATE dates
SET value = ADD_MONTHS(
value,
CEIL( MONTHS_BETWEEN( TRUNC( SYSDATE, 'MM' ), value ) )
);
Query 1:
SELECT * FROM dates
Results:
| VALUE |
|----------------------|
| 2017-11-03T00:00:00Z |
| 2017-11-29T00:00:00Z |
| 2017-11-15T00:00:00Z |
| 2017-11-30T00:00:00Z | -- There are not 31 days in November
Probably you want
update your_table
set this_date = add_months(this_date, 5)
where ...
This will add five months to the selected dates.
Your edited question says you want to update all the dates to the current month and year; you can automate it like this ...
update your_table
set this_date = add_months(this_date,
months_between(trunc(sysdate,'mm'), trunc(this_date, 'mm')))
-- or whatever filter you require
where this_date between trunc(sysdate, 'yyyy') and sysdate
/
Using month_between() guarantees that you won't get invalid dates such as '2017-11-31'. You say in a comment that all the dates will be < 05.mm.yyyy but your sample data disagrees. Personally I'd go with a solution that doesn't run the risk of data integrity issues, because the state of your data tomorrow may will be different from its state today.
Check out the LiveSQL demo.
I would start off with something like this to get my dates and then craft an update from it (substitute old_date with your date column and source_table with the table name):
select old_date, to_char(sysdate, 'YYYY-MM-') || to_char(old_date, 'DD') from source_table;

SQL select unique elements and compare them on two periods

Lets say we have a table that looks like this:
I want to be able to see how many URL records are there during period1 and period2.
where period 1 is "date > '2016-01-01' and date < '2017-01-01' "
and period 2 is "date > '2014-01-1' and date < '2015-01-01' "
Here is what visualization of my expectations :
I can easily do this with one single period using following query:
SELECT URL, COUNT(URL) as Period1
FROM table WHERE date < '2017-01-01'
AND date > '2016-01-01' GROUP BY URL
But how do I add second column with Period2?
Any thoughts would be much appreciated. Sorry if I explained myself incorrectly.
Just change the dates in below query and it will count the hits per period
SELECT [URL]
,SUM(CASE WHEN (date >= '12/22/2015' And date <='12/23/2015') THEN 1 Else 0 END)
,SUM(CASE WHEN (date > '12/30/2015' And date < '12/31/2015') THEN 1 Else 0 END)
FROM LogFilesv2_Dataset.DE_Visits
Group by URL
for BigQuery Standard SQL
#standardSQL
SELECT
URL AS uri,
COUNTIF(date BETWEEN '2016-01-01' AND '2016-12-31') AS Period1,
COUNTIF(date BETWEEN '2014-01-01' AND '2014-12-31') AS Period2
FROM `LogFilesv2_Dataset.DE_Visits`
GROUP BY URL
Not sure which database you are using. But for Oracle database you can try using scalar sub-queries like this.
select url,(select count(*) from test where url=t.url and date_col <= sysdate and date_col > sysdate-20) period1,(select count(*) from test where url=t.url and date_col <= sysdate and date_col > sysdate-40) period2
from test t group by url;
You can replace date range appropriately in the query above.
It is always helpful to provide SQL scripts to create the table and populate the data.

How to Average column on bottom of query

Ignore '?DATE1::?' it is just a prefix for users to input date range.
Select
STARTDATEKEY
round(avg(Minutes),2) as Time /*average for 1 day */
from Table
where To_Date(to_char(StartDate, 'DD-MON-YYYY')) >= To_Date('?DATE1::?','MM/DD/YYYY')
and To_Date(to_char(RESTOREDDATETIME, 'DD-MON-YYYY')) <= To_Date('?DATE2::?','MM/DD/YYYY')
and FLAG = 0
group by STARTDATEKEY
Out will be
I need help showing average for column Time on bottom of 20130110 52.67
note to editor/reviewer : I don't know if I should tag Oracle or SQL.
You can use the ROLLUP grouping function.
Should be something like this:
Select
STARTDATEKEY
round(avg(Minutes),2) as Time /*average for 1 day */
from Table
where To_Date(to_char(StartDate, 'DD-MON-YYYY')) >= To_Date('?DATE1::?','MM/DD/YYYY')
and To_Date(to_char(RESTOREDDATETIME, 'DD-MON-YYYY')) <= To_Date('?DATE2::?','MM/DD/YYYY')
and FLAG = 0
group by ROLLUP(STARTDATEKEY)
Here is a simplified sqlfiddle demo

Find latest value earlier than specified date

I have exchange rate table in which there are multiple date wise records with exchange rate.
Date Rate
17/05/2012 5
23/05/2012 6
27/05/2012 7
Now I want rate while passing any date like if, I pass 20/05/2012 then rate 5 should return because 20/05/2012 elapse in date range 17 and 23 may 2012.
Assuming you have correct datatypes (that is, not varchar to store date values...)
SELECT TOP 1
Rate
FROM
MyTable
WHERE
DateColumn <= '20120520'
ORDER BY
DateColumn DESC
Something like this will work:
select Rate from tablename where Date in (
select max(Date) as Date
from tablename
where Date <= convert(datetime, '20/05/2012', 103)
)