DB2: substring a number - db2

In my dataset I have a variable (numeric) which is year+month, called year_month with values 201702, 201703 etc.
Normally my code looks like this:
select
year_month
,variable2
,variable3
from dataset
I wish to extract the month and the year from the year_month variable, but I'm not sure how to do this when year_month is numeric.
edit: not a duplicate, different problem, I do not care about dates.

To extract the date parts from an integer
SELECT year_month/100,MOD(year_month,100)
To fully convert the integer to a date :
SELECT TO_DATE(CHAR(year_month),'YYYYMM')

Possible with this methods too:
select left(cast(year_mont as varchar(6)), 4) as YYYY,
right(cast(year_mont as varchar(6)), 2) as MM from yourtable
You can have a timestamp like this:
select TIMESTAMP_FORMAT(cast(year_mont as varchar(6)), 'YYYYMM') as YouTimeStamp
from yourtable
Or a date too:
select Date(TIMESTAMP_FORMAT(cast(year_mont as varchar(6)), 'YYYYMM')) as YouTimeStamp
from yourtable

Related

T-SQL apply where clause to function fields not working

I'm having a hard time filtering this view by CreateDate. The CreateDate in the table is in the following format: 2013-10-14 15:53:33.900
I managed to DATEPART the year month and day into separate columns, but now it's not letting me use my WHERE clause on those newly created columns. Specifically, the error is "Invalid Column Name CreateYear" for both lines. What am I doing wrong here guys? Is there a better/easier way to do this than parse out the day, month, and year? It seems overkill. I've spent quite a bit of hours on this to no avail.
SELECT convert(varchar, DATEPART(month,v.CreateDate)) CreateMonth,
convert(varchar, DATEPART(DAY,v.CreateDate)) CreateDay,
convert(varchar, DATEPART(YEAR,v.CreateDate)) CreateYear,
v.CreateDate,
v.customerName
From
vw_Name_SQL_DailyPartsUsage v
full outer join
ABC.serviceteamstechnicians t on v.TechnicianNumber = t.AgentNumber
full outer join
ABC.ServiceTeams s on t.STID = s.STID
where
CreateYear >= '02/01/2018'
and
CreateYear <= '02/20/2018'
You cannot reference an alias from the select in the where
Even if you could why would you expect year to be '02/01/2018'
Why are you converting to varchar
where year(v.CreateDate) = 2018
or
select crdate, cast(crdate as date), year(crdate), month(crdate), day(crdate)
from sysObjects
where cast(crdate as date) <= '2014-2-20'
and cast(crdate as date) >= '2000-2-10'
order by crdate
You could use:
SELECT convert(varchar, DATEPART(month,v.CreateDate)) CreateMonth,
convert(varchar, DATEPART(DAY,v.CreateDate)) CreateDay,
convert(varchar, DATEPART(YEAR,v.CreateDate)) CreateYear,
v.CreateDate,
v.customerName
From vw_Name_SQL_DailyPartsUsage v
full outer join
ABC.serviceteamstechnicians t on v.TechnicianNumber = t.AgentNumber
full outer join
ABC.ServiceTeams s on t.STID = s.STID
where CreateDate BETWEEN '20180102' and '20180220';
More info about the logical query processing is that you cannot refer to a column alias at SELECT in the WHERE clause without using a subquery/CROSS APPLY.

Google BigQuery: Select and group by "yyyy-mm" from date field ("yyyy-mm-dd") or timestamp

I would like to group by "yyyy-mm" from a date field ("yyyy-mm-dd") or timestamp field so that I can pull and group transactional data over multiple years without having to pull separate queries grouping by month for each year.
SELECT
CONCAT(STRING(YEAR(timestamp)),'-',RIGHT(STRING(100 + MONTH(timestamp)), 2)) AS yyyymm,
<any aggregations here>
FROM YourTable
GROUP BY 1
another option:
SELECT
STRFTIME_UTC_USEC(timestamp, "%Y-%m") AS yyyymm,
<any aggregations here>
FROM YourTable
GROUP BY 1
both versions should work with timestamp or date
You can use the following for Standard SQL:
SELECT concat(cast(format_date("%E4Y", cast(current_date() as date)) as string),'-',cast(format_date("%m", cast(current_date() as date)) as string)) as yyyymm, <other aggregations>
FROM <YourTable>
GROUP BY 1;
Just replace the current_date() with your column name containing the timestamp.

PostgreSQL SELECT date before max(DATE)

I need to select the rows for which the difference between max(date) and the date just before max(date) is smaller than 366 days. I know about SELECT MAX(date) FROM table to get the last date from now, but how could I get the date before?
I would need a query of this kind:
SELECT code, MAX(date) - before_date FROM troncon WHERE MAX(date) - before_date < 366 ;
NB : before_date does not refer to anything and is to be replaced by a functionnal stuff.
Edit : Example of the table I'm testing it on:
CREATE TABLE troncon (code INTEGER, ope_date DATE) ;
INSERT INTO troncon (code, ope_date) VALUES
('C086000-T10001', '2014-11-11'),
('C086000-T10001', '2014-11-11'),
('C086000-T10002', '2014-12-03'),
('C086000-T10002', '2014-01-03'),
('C086000-T10003', '2014-08-11'),
('C086000-T10003', '2014-03-03'),
('C086000-T10003', '2012-02-27'),
('C086000-T10004', '2014-08-11'),
('C086000-T10004', '2013-12-30'),
('C086000-T10004', '2013-06-01'),
('C086000-T10004', '2012-07-31'),
('C086000-T10005', '2013-10-01'),
('C086000-T10005', '2012-11-01'),
('C086000-T10006', '2014-04-01'),
('C086000-T10006', '2014-05-15'),
('C086000-T10001', '2014-07-05'),
('C086000-T10003', '2014-03-03');
Many thanks!
The sub query contains all rows joined with the unique max date, and you select only ones which there differente with the max date is smaller than 366 days:
select * from
(
SELECT id, date, max(date) over(partition by code) max_date FROM your_table
) A
where max_date - date < interval '366 day'
PS: As #a_horse_with_no_name said, you can partition by code to get maximum_date for each code.

Using resulting field in ORDER BY

I will post a simple example:
SELECT " CAST(t.PurchaseDate AS DATE) AS PurchaseDate
FROM SomeTable t
ORDER BT PurchaseDate
How can I make sure that ORDER BY will use PurchaseDate (only DATE part), and not PurchaseDate table field?
I know I can name CAST result as PurchaseDate2 (or whatever), but I do not see that as a very intuitive solution.
SELECT " CAST(t.PurchaseDate AS DATE) AS PurchaseDate2
FROM SomeTable t
ORDER BT PurchaseDate2
Also I can use CAST again:
ORDER BY CAST(t.PurchaseDate AS DATE)
but I am wondering if I can avoid double CAST?
Any ideas how can we (and can we) reference a resulting field in ORDER BY, and not the table field, when they have the same name?
Syntax of the '' aside....It's not a solution, as the order by clause uses table column names, not statement alias names. If you're looking for something this specific:
SELECT " PurchaseDate
FROM (
SELECT " CAST(t.PurchaseDate AS DATE) AS PurchaseDate
FROM SomeTable t
) AnotherTable
ORDER BT PurchaseDate
You can use CONVERT() function as below which will get only DATE part
SELECT CONVERT(date, t.PurchaseDate) AS PurchaseDate
FROM SomeTable t
ORDER BT PurchaseDate
First of all, you should change the alias name to different then actual column name. Something like NewPurchaseDate. Not sure why you want to keep it same like actual column name.
second, you can do something like below, instead of using the column alias use the actual conversion processing in order by
SELECT CONVERT(date, t.PurchaseDate) AS PurchaseDate
FROM SomeTable t
ORDER BY CONVERT(date, t.PurchaseDate)
Does not have the ugly factor of PurchaseDate2
SELECT CAST(t.PurchaseDate AS DATE) AS [Purchase Date]
FROM SomeTable t
ORDER BY [Purchase Date]

How to sort this data inside the field based on the recent Date

I have a data in the field as " Date: 03-21-13 12/13/14/15 Date:04-21-13 39/12/34/14 Date:04-19-13 19/45/65/12 ".How to sort this data inside the field based on the recent Date.
It should Look like
Date:04-21-13 39/12/34/14
Date:04-19-13 19/45/65/12
Date: 03-21-13 12/13/14/15
Because you are storing it as text, you cannot correctly sort directly on the column (as you appear to have discovered). You will need to split the column, and then sort on that. Something like:
Declare #tvTable Table (
TextColumn varchar(max)
)
Insert #tvTable
Select '04-19-13 19/45/65/12'
Union All
Select '04-21-13 39/12/34/14'
Union All
Select '03-21-13 12/13/14/15'
Union All
Select '03-25-13 17/18/19/20'
Union All
Select '05-01-13 99/88/77/66'
Union All
Select '02-01-13 11/22/33/44'
Select t.TextColumn
From #tvTable t
Cross Apply dbo.fncDelimitedSplit8k(TextColumn, ' ') split
Where split.ItemNumber = 1
Order By Cast(split.Item As DateTime) Desc
The split function taken from Jeff Moden Tally OH!