Use of After, Before, Include in Temporal Database - sql

First of all thank you to read me and try to help me.
I am starting to working with temporal database, exactly with bitemporal database with the next structure:
CREATE TABLE poblat (
dni VARCHAR2(9),
name VARCHAR(12),
tiv DATE,
tfv DATE,
tit TIMESTAMP,
tft TIMESTAMP,
PRIMARY KEY (dni,tiv, tit)
);
I would to know how can i do a query using a clause like after, before or include.
For example i do this:
SELECT nombre, tiv, tfv FROM poblat
WHERE (tiv, tfv) INCLUDE (to_date('31/12/2014'), to_date('31/12/2016'));
But sql developer says that im using an "invalid relational operator".
Thank you for your attention and for your help.

Presumably your WHERE clause is specifying a date range and you are looking for records which fall within that range. If so:
SELECT nombre, tiv, tfv
FROM poblat
WHERE tiv > =to_date('31/12/2014') -- start of date range
and tfv <= to_date('31/12/2016') -- end of date range
;

there is no INCLUDE is Oracle's SQL. According to bitemporal db's document http://docs.marklogic.com/guide/temporal/searching#id_78584 , there's two consecutive Allen operators seem complying with include :
aln_equals : x-start = y-start and x-end = y-end aln_contains :
x-start < y-start and x-end > y-end
( where X and Y are both periods )
may result in Oracle :
SELECT nombre, tiv, tfv FROM poblat WHERE to_date(tiv,'dd/mm/yyyy') >= to_date('31/12/2014','dd/mm/yyyy') and to_date(tif,'dd/mm/yyyy') <= to_date('31/12/2016','dd/mm/yyyy');

Related

Syntax error using the WITH clause

I am trying to setup a CTE table with a series of quarterly dates.
The query returns [42601] ERROR: syntax error at or near "values" Position: 38
with q(qqyy, firstday, lastday) as (
values
('Q4_10', '09-30-2010', '12-31-2010'),
('Q1_11', '12-31-2010', '03-31-2011'),
('Q2_11', '03-31-2011', '06/30/2011'),
('Q3_11', '06/30/2011', '09/30/2011'),
('Q4_11', '09/30/2011', '12/31/2011'),
('Q1_12', '12/31/2011', '03/31/2012'),
('Q2_12', '03/31/2012', '06/30/2012'),
('Q3_12', '06/30/2012', '09/30/2012'),
('Q4_12', '09/30/2012', '12/31/2012'),
('Q1_13', '12/31/2012', '03/31/2013'),
('Q2_13', '03/31/2013', '06/30/2013'),
('Q3_13', '06/30/2013', '09/30/2013'),
('Q4_13', '09/30/2013', '12/31/2013'),
('Q1_14', '12/31/2013', '03/31/2014'),
('Q2_14', '03/31/2014', '06/30/2014'),
('Q3_14', '06/30/2014', '09/30/2014'),
('Q4_14', '09/30/2014', '12/31/2014'),
('Q1_15', '12/31/2014', '03/31/2015'),
('Q2_15', '03/31/2015', '06/30/2015'),
('Q3_15', '06/30/2015', '09/30/2015'),
('Q4_15', '09/30/2015', '12/31/2015'),
('Q1_16', '12/31/2015', '03/31/2016'),
('Q2_16', '03/31/2016', '06/30/2016'),
('Q3_16', '06/30/2016', '09/30/2016'),
('Q4_16', '09/30/2016', '12/31/2016')
)
SELECT q.qqyy, cobrand_id, sum(calc)
into temp_08.cmg_calc
from temp_08.cmg s
join q on
s.transaction_date >= q.firstday
and s.transaction_date <= q.lastday
GROUP BY q.qqyy, cobrand_id;
It appears that the above query is getting stuck on "values" due to Redshift using an older version of postgresql (http://docs.aws.amazon.com/redshift/latest/dg/c_unsupported-postgresql-features.html). But for some reason the below query that also uses "values" works fine. Any idea how I can get the above query to work using redshift?
create table temp_08.cmgquarters (
quarter_col text
, date_from date
, date_to date
);
insert into temp_08.cmgquarters
values
('Q4_10', '09-30-2010', '12-31-2010'),
('Q1_11', '12-31-2010', '03-31-2011'),
('Q2_11', '03-31-2011', '06/30/2011'),
('Q3_11', '06/30/2011', '09/30/2011'),
('Q4_11', '09/30/2011', '12/31/2011'),
('Q1_12', '12/31/2011', '03/31/2012'),
('Q2_12', '03/31/2012', '06/30/2012'),
('Q3_12', '06/30/2012', '09/30/2012'),
('Q4_12', '09/30/2012', '12/31/2012'),
('Q1_13', '12/31/2012', '03/31/2013'),
('Q2_13', '03/31/2013', '06/30/2013'),
('Q3_13', '06/30/2013', '09/30/2013'),
('Q4_13', '09/30/2013', '12/31/2013'),
('Q1_14', '12/31/2013', '03/31/2014'),
('Q2_14', '03/31/2014', '06/30/2014'),
('Q3_14', '06/30/2014', '09/30/2014'),
('Q4_14', '09/30/2014', '12/31/2014'),
('Q1_15', '12/31/2014', '03/31/2015'),
('Q2_15', '03/31/2015', '06/30/2015'),
('Q3_15', '06/30/2015', '09/30/2015'),
('Q4_15', '09/30/2015', '12/31/2015'),
('Q1_16', '12/31/2015', '03/31/2016'),
('Q2_16', '03/31/2016', '06/30/2016'),
('Q3_16', '06/30/2016', '09/30/2016'),
('Q4_16', '09/30/2016', '12/31/2016');
With Redshift not supporting the values() as a "table replacement" you need to re-write that as a union:
with q(qqyy, firstday, lastday) as (
select 'Q4_10', '09-30-2010', '12-31-2010' union all
select 'Q1_11', '12-31-2010', '03-31-2011' union all
....
)
SELECT ...;
you should however user proper DATE literals:
with q(qqyy, firstday, lastday) as (
select 'Q4_10', DATE '2010-09-30', DATE '2010-12-31' union all
select 'Q1_11', DATE '2010-12-31', DATE '2011-03-31' union all
....
)
SELECT ...;
I don't know Postgres well enough, but with SQL-Server you cannot use the VALUES like a table directly. You must use parenthesis around and provide a table alias with column names to define the derived table.
This would be something like this:
with q as (
select * from
(
values
('Q4_10', '09-30-2010', '12-31-2010'),
('Q1_11', '12-31-2010', '03-31-2011'),
('Q2_11', '03-31-2011', '06/30/2011'),
('Q3_11', '06/30/2011', '09/30/2011'),
('Q4_11', '09/30/2011', '12/31/2011'),
('Q1_12', '12/31/2011', '03/31/2012'),
('Q2_12', '03/31/2012', '06/30/2012'),
('Q3_12', '06/30/2012', '09/30/2012'),
('Q4_12', '09/30/2012', '12/31/2012'),
('Q1_13', '12/31/2012', '03/31/2013'),
('Q2_13', '03/31/2013', '06/30/2013'),
('Q3_13', '06/30/2013', '09/30/2013'),
('Q4_13', '09/30/2013', '12/31/2013'),
('Q1_14', '12/31/2013', '03/31/2014'),
('Q2_14', '03/31/2014', '06/30/2014'),
('Q3_14', '06/30/2014', '09/30/2014'),
('Q4_14', '09/30/2014', '12/31/2014'),
('Q1_15', '12/31/2014', '03/31/2015'),
('Q2_15', '03/31/2015', '06/30/2015'),
('Q3_15', '06/30/2015', '09/30/2015'),
('Q4_15', '09/30/2015', '12/31/2015'),
('Q1_16', '12/31/2015', '03/31/2016'),
('Q2_16', '03/31/2016', '06/30/2016'),
('Q3_16', '06/30/2016', '09/30/2016'),
('Q4_16', '09/30/2016', '12/31/2016')
) AS tbl(qqyy, firstday, lastday)
)
SELECT *
from q
Attention
You are in high danger!
You are using culture dependant date formats. This might work in your system, but break on another one...
Further more, your are not even consistent!
Your VALUES provide your date values as string.
In SQL-Server I'd suggest to use ISO8601, unseparated or - my favourite - ODBC. But I'm sure there are culture independent formats for literal dates in Postgres too.
And I would suggest to let the CTE come back with typed values or use a temp table with typed columns.

Update Query depending on Date

RN_TESTCYCL_ID
RN_CYCLE_ID
RN_TEST_ID
RN_RUN_ID
RN_RUN_NAME
RN_EXECUTION_DATE (if RN_VTS Null, compare with this Date, format: DDMMYY)
RN_EXECUTION_TIME
RN_HOST
RN_STATUS
RN_DURATION
RN_TESTER_NAME
RN_PATH
RN_USER_01
RN_USER_02
RN_USER_03
RN_USER_04
RN_USER_05
RN_USER_06
RN_USER_07
RN_USER_08
RN_USER_09
RN_USER_10
RN_USER_11
RN_USER_12
RN_TEST_VERSION
RN_ATTACHMENT
RN_RUN_VER_STAMP
RN_VTS (compare with current Date, sometimes Null, Format: YYYYMMDDHH24MISS)
RN_CYCLE
RN_TEST_INSTANCE
RN_OS_NAME
RN_OS_SP
RN_OS_BUILD
RN_VC_LOKEDBY
RN_VC_STATUS
RN_VC_VERSION
RN_OS_CONFIG
RN_ASSIGN_RCYC
RN_BPTA_CHANGE_DETECTED
RN_BPTA_CHANGE_AWARENESS
RN_VC_VERSION_NUMBER
RN_PINNED_BASELINE
RN_TEST_CONFIG_ID
RN_DRAFT
RN_ITERS_PARAMS_VALUES
RN_ITERS_SUM_STATUS
RN_BPT_STRUCTURE
RN_STATE
RN_COMMENTS
RN_SUBTYPE_ID
RN_TEXT_SYNC
RN_ENVIRONMENT
RN_BUILD_REVISION
RN_DETAIL
RN_JENKINS_URL
RN_JENKINS_JOB_NAME
RN_RESULTS_FILES_NETWORK_PATH
I need to update every RN_Tester_name to "anonymous" if RN_VTS < DateX and if RN_VTS is Null then compare RN_EXECUTION_DATE < DateX
Can someone figure out a query to update RN_Tester_Name, i'm kinda stuck?
Use coalesce SQL function to select the first non-null column. Here you see an example oraclesql update statement:
update X set
rn_tester_name = 'anonymous'
where coalesce(rn_vts, rn_execution_date) < Y
I don't know how you can use that in your vb.net code thought.

data arguments are not working as expected in Hive

I am passing data parameters to hive script, but it's not working.
SET yrmonth=concat(substr(to_date(${hiveconf:runningdate}),1,4),substr(to_date(${hiveconf:runningdate}),6,2));
SET fom=TRUNC(${hiveconf:runningdate},'MONTH');
SET lom=LAST_DAY(${hiveconf:runningdate});
USE cust_db;
SELECT saleid,podid,pname
FROM product
WHERE productln_yrmo=${hiveconf:yrmonth};
--productln_yrmo is int column
SELECT cid,cname,cloc
FROM customer
WHERE customer_createddt >='${hiveconf:fom}'
AND customer_createddt <='${hiveconf:lom}'
AND cloc = 'AUS';
--customer_createddt is date column
hive -hiveconf runningdate='2016-05-18' -f cust.hql
from your query, 'customer_createddt' seems to be DATE type since you have used with '<=' and '>=' operators to get the range of values between 'fom' and 'lom'. I guess lexicographic comparison for date range works fine perfectly . But, not sure when table DDL created with a partition on 'customer_createddt' column.
So please give a try casting string to date ( also please post your table DDL for more clarity)
SELECT cid,cname,cloc
FROM customer
WHERE customer_createddt >=CAST(${hiveconf:fom} AS DATE)
AND customer_createddt <=CAST(${hiveconf:lom} AS DATE)
AND cloc = 'AUS';

Need to optimize a SQL Query

Here is the where clause of the SQL. when I'm removing this part, it's taking 3 mins to execute, with this one it's taking more than 15 mins
there are almost 9000 records in DB
WHERE username = 'xyz' AND
(
( acceptedfordeliverytime BETWEEN '2012-9-1' AND '2013-1-29' )
OR
(
YEAR(acceptedfordeliverytime) = YEAR('2013-1-29')
AND
MONTH(acceptedfordeliverytime) = MONTH('2013-1-29')
AND
DAY(acceptedfordeliverytime) = DAY('2013-1-29')
)
OR
(
YEAR(acceptedfordeliverytime) = YEAR('2012-9-1')
AND
MONTH(acceptedfordeliverytime) = MONTH('2012-9-1')
AND
DAY(acceptedfordeliverytime) = DAY('2012-9-1')
)
)
Why don't you just use:
WHERE username = 'xyz' AND
(acceptedfordeliverytime >= '2012-09-01' AND
acceptedfordeliverytime < '2013-01-30'
)
This will also allow an index on (username, acceptedfordeliverytime) to be used when executing the query.
I think this will give you the same results.
and also make an index for column acceptedfordeliverytime to speed up searching.
WHERE username = 'xyz' AND acceptedfordeliverytime BETWEEN '2012-9-1' AND '2013-1-29'
Isn't BETWEEN inclusive? This would mean that you don't need all the extra clauses (that check for the first and last date in a VERY elaborate way). I believe your query would return the same result if you just did:
WHERE username = 'xyz' AND
(
acceptedfordeliverytime BETWEEN '2012-9-1' AND '2013-1-29'
)
Your both OR part is unnecessary.
when you use
acceptedfordeliverytime Between '2012-9-1' AND '2013-1-29'
It used both date included so OR part is not needed. if you have date and time in your database then you can convert it into date like this
CAST(acceptedfordeliverytime as date) Between '2012-9-1' AND '2013-1-29'

LINQ to SQL selecting records and converting dates

I'm trying to select records from a table based on a date using Linq to SQL. Unfortunately the date is split across two tables - the Hours table has the day and the related JobTime table has the month and year in two columns.
I have the following query:
Dim qry = From h As Hour In ctx.Hours Where Convert.ToDateTime(h.day & "/" & h.JobTime.month & "/" & h.JobTime.year & " 00:00:00") > Convert.ToDateTime("01/01/2012 00:00:00")
This gives me the error "Arithmetic overflow error converting expression to data type datetime."
Looking at the SQL query in SQL server profiler, I see:
exec sp_executesql N'SELECT [t0].[JobTimeID], [t0].[day], [t0].[hours]
FROM [dbo].[tbl_pm_hours] AS [t0]
INNER JOIN [dbo].[tbl_pm_jobtimes] AS [t1] ON [t1].[JobTimeID] = [t0].[JobTimeID]
WHERE (CONVERT(DateTime,(((((CONVERT(NVarChar,[t0].[day])) + #p0) + (CONVERT(NVarChar,COALESCE([t1].[month],NULL)))) + #p1) + (CONVERT(NVarChar,COALESCE([t1].[year],NULL)))) + #p2)) > #p3',N'#p0 nvarchar(4000),#p1 nvarchar(4000),#p2 nvarchar(4000),#p3 datetime',#p0=N'/',#p1=N'/',#p2=N' 00:00:00',#p3='2012-01-31 00:00:00'
I can see that it's not passing in the date to search for correctly but I'm not sure how to correct it.
Can anyone please help?
Thanks,
Emma
The direct cause of the error may have to do with this issue.
As said there, the conversions you use are a very inefficient way to build a query. On top of that, it is inefficient because the expressions are not sargable. I.e. you are using a computed value from database columns in a comparison which disables the query analyzer to use indexes to jump to individual column values. So, you could try to fix the error by doctoring the direct cause, but I think it's better to rewrite the query in a way that only the single column values are used in comparions.
I've worked this out in C#:
var cfg = new DateTime(12,6,12);
int year = 12, month = 6, day = 13; // Try some more values here.
// Date from components > datetime value?
bool gt = (
year > cfg.Year || (
(year == cfg.Year && month > cfg.Month) || (
year == cfg.Year && month == cfg.Month && day > cfg.Day)
)
);
You see that it's not as straightforward as it may look at first, but it works. There are much more comparisons to work out, but I'm sure that the ability to use indexes will easily outweigh this.
A more straightforward, but not sargable, way is to use sortable dates, like 20120101 and compare those (as integers).