get Unique Month-Year combination from SQlite database - ios

I have NSDate stored in my sqlite table in double format - using timeIntervalSince1970 funciton.
Now I want to retrive unique date combinatios like
{
January 2014
December 2013
November 2013
December 2012
November 2012
October 2011
}
Data have to be in sorted order. How can I get data in this format?
I have tried with Date function
SELECT date(DateInterval, '%m', '%Y') FROM MyTable
but got no result.
Hope for good helps :)
Thanks in Advance.

Are you looking for something like this?
SELECT CASE m
WHEN '01' THEN 'January'
WHEN '02' THEN 'Febuary'
WHEN '03' THEN 'March'
WHEN '04' THEN 'April'
WHEN '05' THEN 'May'
WHEN '06' THEN 'June'
WHEN '07' THEN 'July'
WHEN '08' THEN 'August'
WHEN '09' THEN 'September'
WHEN '10' THEN 'October'
WHEN '11' THEN 'November'
WHEN '12' THEN 'December'
END || ' ' || y AS dates
FROM
(
SELECT DISTINCT
strftime('%m', DateInterval, 'unixepoch') m,
strftime('%Y', DateInterval, 'unixepoch') y
FROM MyTable
) q
ORDER BY y DESC, m DESC
Sample output:
| dates |
|---------------|
| January 2014 |
| December 2013 |
| November 2013 |
| October 2013 |
Here is a SQLFiddle demo

It is MySQL, then Use DATE_FORMAT function to fetch in a specific format for display.
SELECT
date_format(DateInterval, '%M %Y') as dates
FROM MyTable
order by
date_format( DateInterval, '%Y%m' ) desc;

Related

Rails has_many sorting of a column based on latest created_at record

I have two models named as 'customer' and 'membership'. customer can have many memberships. I want to sort records based on membership's created_at and cancelled_at date columns. membership record should be a latest record created and cancelled should not include nil value. For example if a customer with id 1 has two membership records with created_at as 25 Dec 2020 and 27 Dec 2020 and cancelled dates as 1 jan 2021 and nil then this record should go to the bottom as latest membership is still active as its cancelled_at date is nil and should not come in asc or desc sorted list. But if a customer has 2 memberships with created_at as 25 Dec 2020 and 27 Dec 2020 and cancelled dates as 1 jan 2000 and 5 Jan 2000 then a record should popup with cancelled date as 5 Jan 2000.
Database Table - Customer
Id Name
1 A
2 B
3 C
4 D
5 E
Database Table - Membership
id customer_id created_at cancelled_at
1 1 1 jan 2000 5 jan 2000
2 1 2 jan 2000 nil
3 2 1 Dec 1999 2 Dec 1999
4 5 15 Jan 2000 16 Jan 2000
5 5 17 Jan 2000 20 Jan 2000
Then result should be (for asc order of cancelled_at)
customer_id name cancelled at
2 B 2 Dec 1999
5 E 20 Jan 2000
1 A nil
3 C nil
4 D nil
My query which is not producing desired output:
Customer.joins('LEFT JOIN memberships')
.where("memberships.cancel_at = (SELECT MAX(memberships.cancel_at) FROM memberships WHERE customers.id = memberships.customer_id)")
.group('customers.id')
.order('MAX(memberships.created_at) ASC')
One very efficient way to solve this is with a lateral join:
SELECT c.*, latest_membership.cancelled_at AS cancelled_at
FROM customers c
LEFT JOIN LATERAL (
SELECT cancelled_at
FROM memberships m
WHERE m.customer_id = c.id -- lateral reference
ORDER BY m.created_at
LIMIT 1
) AS latest_membership ON TRUE
ORDER BY latest_membership.cancelled_at ASC NULLS LAST
This fancy new toy can be a bit hard to wrap your head around but its basically like a foreach loop - except in SQL. PostgreSQL will iterate over each row in a result set and evaluate a subquery using that row as a parameter. Crazy stuff!
ActiveRecord does not support lateral joins "out of the box" since its a fairly Postgres specific feature and it aims at being polyglot. But you can create them with either SQL strings or Arel.
Customer
.select(
'customers.*',
'latest_membership.cancelled_at AS cancelled_at'
)
.joins(<<~SQL)
LEFT JOIN LATERAL (
SELECT cancelled_at
FROM memberships m
WHERE m.customer_id = c.id -- lateral reference
ORDER created_at
LIMIT 1
) AS latest_membership ON TRUE
SQL
.order('latest_membership.cancelled_at ASC NULLS LAST')

What datatype is used to insert only 'YEAR' in Informix?

I am trying to create a table in that one column should accept only 'YEAR'
eg: 2017, 2018, 2019 along with 'CURRENT YEAR' as default value.
I am unable to create such a column — can you please help me?
Expected Output :
ID Today_Year
----- -----------
100 2017
101 2018
102 2018
The database server is Informix.
You could do that as follows:
create table t2 (c1 datetime year to year default current year to year, c2 int);
insert into t2 (c2) values(100);
insert into t2 values ('2017',101);
insert into t2 values (current,102);
select * from t2;
c1 c2
2018 100
2017 101
2018 102
You can use any of a number of types. The 'obvious' one is:
DATETIME YEAR TO YEAR
The least obvious one is:
INTERVAL YEAR TO YEAR — not recommended
The other alternative is simply an integer type:
SMALLINT
INTEGER
BIGINT — overkill; not recommended
INT8 — deprecated; do not use
The integer types may be easier to use in the long run than DATETIME YEAR TO YEAR; I'd almost certainly use INTEGER or SMALLINT.
How can I create a table with a 'year' column and the default value in that column is the current year?
Hmmm; that's hard to do with an INTEGER type. At that point, DATETIME comes to the rescue:
CREATE TABLE YearTable
(
RowNumber SERIAL NOT NULL PRIMARY KEY,
YearColumn DATETIME YEAR TO YEAR NOT NULL DEFAULT CURRENT YEAR TO YEAR,
DateColumn DATE NOT NULL DEFAULT TODAY
);
INSERT INTO YearTable(RowNumber) VALUES(0);
SELECT * FROM YearTable;
That yields, for example (assuming DBDATE=Y4MD- in the environment):
1 2018 2018-03-05
You can't use arbitrary expressions for defaults even when they seem reasonable — which is irksome. Hence, if you need the default, the DATETIME YEAR TO YEAR type is the type of choice. (That's what jrenaut suggested in their answer.)
You could arrange for a trigger with an integer type; that is considerably harder work, though.

Query based on datetime interval

I would like to find out which driver is available during a certain time based on his start and end datetime.
I have two worksheets.
Worksheet1 displayes the start and end time of drivers in datetime:
Driver | Start Time | End Time
------------------------------------------
Driver 1 | 25-05-2015 09:00 | 25-05-2015 15:00
Driver 2 | 25-05-2015 15:00 | 25-05-2015 21:00
Driver 2 | 26-05-2015 09:00 | 26-05-2015 15:00
Driver 1 | 26-05-2015 12:00 | 26-05-2015 17:00
Worksheet2 displays the start date of a tour
Tour 1 | 25-05-2015 11:00
Tour 2 | 25-05-2015 16:00
Tour 3 | 25-05-2015 17:00
Tour 4 | 26-05-2015 09:00
I would like to query in worksheet 2 which driver from worksheet 1 is available during the time of the tour start.
=QUERY(Worksheet1!A:C,"select A where C <= date '"&text(A2,"yyyy-MM-dd")&"'",0)
But I understand that I will need to be working with timedate instead (to get the actual times of the start and end of the shifts) and I will need to query an interval.
If you want to use dates and times, you need datetime instead of date. And since there is an interval, another comparison should be made with column B. The query string, shown with linebreaks for readability, would be
"select A
where B <= datetime '" & text(A2, "yyyy-MM-dd hh:mm:ss") & "'
and C >= datetime '" & text(A2, "yyyy-MM-dd hh:mm:ss") & "'"
This ensures that the datetime in A2 is between the datetimes in columns B and C.

LEFT JOIN in SAS using PROC SQL

I am new to SAS and have this basic problem. I have a list of NYSE trading dates in table A as follows -
trading_date
1st March 2012
2nd March 2012
3rd March 2012
4th March 2012
5th March 2012
6th March 2012
I have another table B that has share price information as -
Date ID Ret Price
1st March 2012 1 … …
3rd March 2012 1 … …
4th March 2012 1 … …
5th March 2012 1 … …
6th March 2012 1 … …
1st March 2012 2 … …
3rd March 2012 2 … …
4th March 2012 2 … …
... has numeric data related to price and returns.
Now I need to join the NYSE Data table to the above table to get the following table -
Date ID Ret Price
1st March 2012 1 … …
2nd March 2012 1 0 0
3rd March 2012 1 … …
4th March 2012 1 … …
5th March 2012 1 … …
6th March 2012 1 … …
1st March 2012 2 … …
2nd March 2012 2 0 0
3rd March 2012 2 … …
4th March 2012 2 … …
i.e. a simple left join. The zero's will be filled with . in SAS to indicate missing values, but you get the idea. But if I use the following command -
proc sql;
create table joined as
select table_a.trading_date, table_b.* from table_a LEFT OUTER join table_b on table_a.trading_date=table_b.date;
quit;
The join happens only for the first ID (i.e. ID=1) while for the rest of the IDs, the same data is maintained. But I need to insert the trade dates for all IDs.
How can get the final data without running a do while loop for all IDs? I have 1000 IDs and looping and joining 1000 times is not an option due to limited memory.
Joe is right, you need to take also ID into consideration, but with his solution you cannot get 2nd March 2012 because no one is trading that day. You can do everything with just one sql step (which will take a bit longer):
proc sql;
create table final as
select d.trading_date, d.ID, t.Price, t.Ret
from
(
select trading_date, ID
from table_a, (select distinct ID from table_b)
) d
left join
(
select *
from table_b
) t
on t.Date=d.trading_date and t.ID=d.ID
order by d.id, d.trading_date;
quit;
Your left join doesn't work since it doesn't take ID into account. SAS (or rather SQL) doesn't know that it should repeat by ID.
The easiest way to get the full combination is PROC FREQ with SPARSE, assuming someone has a trade on every valid trading day.
proc freq data=table_b noprint;
tables id*trading_date/sparse out=table_all(keep=id trading_date);
run;
Then join that to the original table_b by id and date.
Alternately, you can use PROC MEANS, which can get your numerics (it can't get characters this way, unless you can use them as a class value).
Using table_b as created by Anton (With ret and price variables):
proc means data=table_b noprint completetypes nway;
class id trading_date;
var ret price;
output out=table_allmeans sum=;
run;
This will output missing for missing rows and values for present rows, and will have a _FREQ_ variable that allows you to differentiate whether a row is really present in the trading dataset or not.
I suppose there must be something off with the data because your query looks fine and worked on the testing data I generated along the lines you described:
data table_a;
format trading_date date9.;
do trading_date= "01MAR2012"d to "06MAR2012"d;
output;
end;
run;
data table_b;
format date date9.;
ret = 0;
price = 0;
do date= "01MAR2012"d to "06MAR2012"d;
do ID = 1 to 4;
if ranuni(123) < 0.3 then
output;
end;
end;
run;
Below is what I get after running your query copied verbatim:
trading_date date ret price ID
01MAR2012 01MAR2012 0 0 3
02MAR2012 02MAR2012 0 0 2
03MAR2012 03MAR2012 0 0 1
03MAR2012 03MAR2012 0 0 2
04MAR2012 04MAR2012 0 0 2
05MAR2012 05MAR2012 0 0 3
06MAR2012 . . . .
It is worth checking the format of your dates- are they numeric? If they are character, are they formatted the same way? If they are numeric, are they dates or datetimes with some odd format applied?

ASP.NET MVC linq-to-entities DateTime

I am having four fields in my LOGIN table , they are userid,username,password,datetime...
In date time field, I set default value to Getdate() ... Now i want to retrive recently registered members to last ...
I mean ,
ex..
uid ... datetime
1 1/21/2011 12:40:12 PM
2 1/23/2011 6:40:12 PM
3 1/24/2011 3:40:12 PM
4 1/24/2011 5:40:12 PM
I need to retrive values as ...
uid ... datetime
4 1/24/2011 5:40:12 PM
3 1/24/2011 3:40:12 PM
2 1/23/2011 6:40:12 PM
1 1/21/2011 12:40:12 PM
How to do this using LINQ query ???
Thank you
This will get you all the users that have logged in in the last 3 day:
(
from l in Logins
where
l.datetime >= System.Data.Objects.SqlClient.SqlFunctions.DateAdd("day", -3, DateTime.Now)
select l
).OrderByDescending(l => l.Data);
If you only want the last 10 users that have logged in, for instance, try this:
(
from l in Logins
select l
).OrderByDescending(l => l.Data).Take(10);

Resources