I have a two tables call RFS and RFS_History.
RFS_id | name
--------+--------
12 | xx
14 | yy
15 | zz
figure 1 :RFS table
RFS_id | gate | End | start
--------+-------+--------+-------
12 | aa | 19/02 | 20/03
12 | bb | 30/01 | 12/08
12 | cc | 30/01 | 12/08
13 | aa | 30/01 | 12/08
12 | dd | 30/01 | 12/08
figure 2 :RFS history
My initial query is a select * query to get information where FRSname ='xx'
SELECT * FROM RFS, RFSHistory
WHERE RFSname="xx" And RFShistory.RFS_ID=RFS.RFS_ID
result is:
RFS_id | gate | End | start
--------+-------+--------+-------
12 | aa | 19/02 | 19/01
12 | bb | 12/04 | 12/02
12 | cc | 20/03 | 12/03
12 | dd | 30/09 | 12/08
figure 3
however I want to get a result like bellow format :
RFS_id | gate_aa | gate_bb | gate_cc | gate_dd
----------------------------------------------
12 | 30 days | 60dyas | 8days | 18days
gate_aa is duraion and it gets from start - end date. Please help me to write single query to get this result.
Use datediff() to get date difference and Pivot() to convert row into cloumn
like here in your case gate wise column
Sample Syntax
SELECT DATEDIFF(day,'2008-06-05','2008-08-05') AS DiffDate
You can use the below query for get the difference b/w dates
SELECT RFS.ID,(RFS_HISTORY.end_t-RFS_HISTORY.start_t) AS DiffDate,gate FROM RFS, RFS_HISTORY
WHERE name='aa' And RFS_HISTORY.ID=RFS.ID group by RFS.ID,gate,RFS_HISTORY.end_t,RFS_HISTORY.start_t
I think you want to convert rows into columns on the values. This can be done with the help of pivoting.
SELECT * FROM RFS, RFSHistory
pivot for columname on [values]
I actually forgot the syntax but you can google it
Related
Write a SQL query to find all dates' id with a higher temperature compared to its previous dates (yesterday).
Try out if you want: https://leetcode.com/problems/rising-temperature/
Input:
Weather table:
+----+------------+-------------+
| id | recordDate | temperature |
+----+------------+-------------+
| 1 | 2015-01-01 | 10 |
| 2 | 2015-01-02 | 25 |
| 3 | 2015-01-03 | 20 |
| 4 | 2015-01-04 | 30 |
+----+------------+-------------+
Output:
+----+
| id |
+----+
| 2 |
| 4 |
+----+
Here's my code:
SELECT w_2.id AS "Id"
FROM Weather w_1
JOIN Weather w_2
ON w_1.id + 1 = w_2.id
WHERE w_1.temperature < w_2.temperature
But my code won't be accepted even if it looks exactly like the expected output.
I know the answer is:
SELECT w2.id
FROM Weather w1, Weather w2
WHERE w2.temperature > w1.temperature
AND DATEDIFF(w2.recordDate, w1.recordDate) = 1
But I tried to not use DATEDIFF because this function is not available in PostgreSQL.
The queries are not compatible. You should join the table on recordDate, not on Id.
SELECT w_2.id AS "Id"
FROM Weather w_1
JOIN Weather w_2
ON w_1.recordDate + 1 = w_2.recordDate
WHERE w_1.temperature < w_2.temperature
Do not assume that Id is sequential and ordered in the same way as recordDate, although the sample data may suggest this.
Say in MonetDB (specifically, the embedded version from the "MonetDBLite" R package) I have a table "events" containing entity ID codes and event start and end dates, of the format:
| id | start_date | end_date |
| 1 | 2010-01-01 | 2010-03-30 |
| 1 | 2010-04-01 | 2010-06-30 |
| 2 | 2018-04-01 | 2018-06-30 |
| ... | ... | ... |
The table is approximately 80 million rows of events, attributable to approximately 2.5 million unique entities (ID values). The dates appear to align nicely with calendar quarters, but I haven't thoroughly checked them so assume they can be arbitrary. However, I have at least sense-checked them for end_date > start_date.
I want to produce a table "nonevent_qtrs" listing calendar quarters where an ID has no event recorded, e.g.:
| id | last_doq |
| 1 | 2010-09-30 |
| 1 | 2010-12-31 |
| ... | ... |
| 1 | 2018-06-30 |
| 2 | 2010-03-30 |
| ... | ... |
(doq = day of quarter)
If the extent of an event spans any days of the quarter (including the first and last dates), then I wish for it to count as having occurred in that quarter.
To help with this, I have produced a "calendar table"; a table of quarters "qtrs", covering the entire span of dates present in "events", and of the format:
| first_doq | last_doq |
| 2010-01-01 | 2010-03-30 |
| 2010-04-01 | 2010-06-30 |
| ... | ... |
And tried using a non-equi merge like so:
create table nonevents
as select
id,
last_doq
from
events
full outer join
qtrs
on
start_date > last_doq or
end_date < first_doq
group by
id,
last_doq
But this is a) terribly inefficient and b) certainly wrong, since most IDs are listed as being non-eventful for all quarters.
How can I produce the table "nonevent_qtrs" I described, which contains a list of quarters for which each ID had no events?
If it's relevant, the ultimate use-case is to calculate runs of non-events to look at time-till-event analysis and prediction. Feels like run length encoding will be required. If there's a more direct approach than what I've described above then I'm all ears. The only reason I'm focusing on non-event runs to begin with is to try to limit the size of the cross-product. I've also considered producing something like:
| id | last_doq | event |
| 1 | 2010-01-31 | 1 |
| ... | ... | ... |
| 1 | 2018-06-30 | 0 |
| ... | ... | ... |
But although more useful this may not be feasible due to the size of the data involved. A wide format:
| id | 2010-01-31 | ... | 2018-06-30 |
| 1 | 1 | ... | 0 |
| 2 | 0 | ... | 1 |
| ... | ... | ... | ... |
would also be handy, but since MonetDB is column-store I'm not sure whether this is more or less efficient.
Let me assume that you have a table of quarters, with the start date of a quarter and the end date. You really need this if you want the quarters that don't exist. After all, how far back in time or forward in time do you want to go?
Then, you can generate all id/quarter combinations and filter out the ones that exist:
select i.id, q.*
from (select distinct id from events) i cross join
quarters q left join
events e
on e.id = i.id and
e.start_date <= q.quarter_end and
e.end_date >= q.quarter_start
where e.id is null;
I am just learning DB Syntax so im sorry if this is not a relevant question.
I'm trying to change the text of a column when a condition is meet. I have tried many things but have not achieved anything.
|---------------------|------------------|------------------|
| Some PK | Some FK | someDatetime |
|---------------------|------------------|------------------|
| 12 | 34 | 1900/01/01 |
|---------------------|------------------|------------------|
| 13 | 54 | 2018/05/32 |
|---------------------|------------------|------------------|
| 15 | 60 | 2000/01/01 |
|------------------------------------------------------------
What i Need is to display this same table, but when the date is lower from 2018(I know that can be achieved with a where), the query brings this back:
|---------------------|------------------|------------------|
| Some PK | Some FK | someDatetime |
|---------------------|------------------|------------------|
| 12 | 34 | ---------- |
| | | or My own string|
|---------------------|------------------|------------------|
| 13 | 54 | 2018/05/32 |
|---------------------|------------------|------------------|
| 15 | 60 | ---------- |
| | | or My own string |
|------------------------------------------------------------
You could use the YEAR function to check the date:
SELECT
PK,
FK,
CASE WHEN YEAR(someDatetime) < 2018
THEN 'my own string'
ELSE CONVERT(VARCHAR, someDatetime, 120) END AS someDatetime
FROM yourTable;
Note that if you want to generate a text column with your message, in the case the year be earlier than 2018, then the entire CASE expression should generate text. So, we can use CONVERT on the datetime column to generate a text version of the date.
use case when and Year function for converting date to year
select some_PK,some_FK,
case when Year(someDatetime)<'2018' then 'My own string' else someDatetime
end as someDatetime
from yourtable
Why wouldn't you just do:
select . . . ,
(case when someDateTime < '2018-01-01'
then 'my own string'
else convert(varchar(255), someDateTime) -- might want to include a format
end)
No function is needed for the date comparison, just a date comparison.
I have data on approx 1000 individuals, where each individual can have multiple rows, with multiple dates and where the columns indicate the program admitted to and a code number.
I need each row to contain a distinct date, so I need to delete the rows of duplicate dates from my table. Where there are multiple rows with the same date, I need to keep the row that has the lowest code number. In the case of more than one row having both the same date and the same lowest code, then I need to keep the row that also has been in program (prog) B. For example;
| ID | DATE | CODE | PROG|
--------------------------------
| 1 | 1996-08-16 | 24 | A |
| 1 | 1997-06-02 | 123 | A |
| 1 | 1997-06-02 | 123 | B |
| 1 | 1997-06-02 | 211 | B |
| 1 | 1997-08-19 | 67 | A |
| 1 | 1997-08-19 | 23 | A |
So my desired output would look like this;
| ID | DATE | CODE | PROG|
--------------------------------
| 1 | 1996-08-16 | 24 | A |
| 1 | 1997-06-02 | 123 | B |
| 1 | 1997-08-19 | 23 | A |
I'm struggling to come up with a solution to this, so any help greatly appreciated!
Microsoft SQL Server 2012 (X64)
The following works with your test data
SELECT ID, date, MIN(code), MAX(prog) FROM table
GROUP BY date
You can then use the results of this query to create a new table or populate a new table. Or to delete all records not returned by this query.
SQLFiddle http://sqlfiddle.com/#!9/0ebb5/5
You can use min() function: (See the details here)
select ID, DATE, min(CODE), max(PROG)
from table
group by DATE
I assume that your table has a valid primary key. However i would recommend you to take IDas Primary key. Hope this would help you.
my table name is tbl1. The fileds are id,name,txdate.
| ID | NAME | TXDATE |
| 1 | RAJ | 1-1-2013 |
| 2 | RAVI | |
| 3 | PRABHU | 25-3-2013 |
| 4 | SAT | |
Now i want to use select query for check txdate < 2-2-2013 in which rows have txdate not empty and the select also retrun which rows have txdate empty.
The Result is like this
| ID | NAME | TXDATE |
| 1 | RAJ | 1-1-2013 |
| 2 | RAVI | |
| 4 | SAT | |
Any feasible solution is there?.
With out using union it is possible?.
Assuming that the TXDATE is of data type DATE then you can use WHERE "TXDATE" < '2013-2-2' OR "TXDATE" IS NULL. Something like:
SELECT *
FROM table1
WHERE "TXDATE" < '2013-2-2'
OR "TXDATE" IS NULL;
See it in action:
SQL Fiddle Demo
I don't now what database your are using and what data type the TXDATE is.
I just tried on my postgreSQL 9.2, with a field "timestamp without time zone".
I have three rows in the table , like:
ac_device_name | ac_last_heartbeat_time
----------------+-------------------------
Nest-Test1 |
Nest-Test3 |
Nest-Test2 | 2013-04-10 15:06:18.287
Then use below statement
select ac_device_name,ac_last_heartbeat_time
from at_device
where ac_last_heartbeat_time<'2013-04-11';
It is ok to return only one record:
ac_device_name | ac_last_heartbeat_time
----------------+-------------------------
Nest-Test2 | 2013-04-10 15:06:18.287
I think you can try statement like:
select * from tbl1 where TXDATE<'2-2-2013' and TXDATE is not NULL
this statement also works in my environment.