I have a table where I have 5 columns which may or may not have dates in them.
| Column A | Column B || Column C | Column D | Column E |
| -------- | -------- || -------- | -------- | -------- |
| Cell 1 | Cell 2 || Cell 3 | Empty | Cell 5 |
| Cell 1 | Empty || Cell 3 | Cell 4 | Cell 5 |
How can I find which date is the nearest to the current date but from each row individually?
To give you more context I have a query which runs in this table (50 columns) and gives me only select columns row by row, and I need the nearest date from these columns to compare it with another date from a different column so I can get the time difference between them.
Here is the SQL code I have:
Related
I have a database that I don't control the source of directly and results in errant '0' entries which mess up generated graphs with these drops to zero. I am able to manipulate the data after the fact and update that database.
It is acceptable that the last known good value can be used instead and so I am trying to make a general query that will remove all the zeros and populate it with the last known value.
Luckily, every entry includes the ID of the last entry and so it is a matter of simply looking back and grabbing it.
I have got very close to a final answer, but instead of updating with the last good value, it just uses the first value over and over again.
dummy data
CREATE TABLE tbl(id INT,r INT,oid INT);
INSERT INTO tbl VALUES(1,10,0);
INSERT INTO tbl VALUES(2,20,1);
INSERT INTO tbl VALUES(3,0,2);
INSERT INTO tbl VALUES(4,40,3);
INSERT INTO tbl VALUES(5,50,4);
INSERT INTO tbl VALUES(6,0,5);
INSERT INTO tbl VALUES(7,70,6);
INSERT INTO tbl VALUES(8,80,7);
SELECT * FROM tbl;
OUTPUT:
| id| r |oid|
|---|----|---|
| 1 | 10 | 0 |
| 2 | 20 | 1 |
| 3 | 0 | 2 | ** NEEDS FIXING
| 4 | 40 | 3 |
| 5 | 50 | 4 |
| 6 | 0 | 5 | ** NEEDS UPDATE
| 7 | 70 | 6 |
| 8 | 80 | 7 |
I have worked several queries to get results around what I am after:
All zero entries:
SELECT * FROM tbl WHERE r = 0;
OUTPUT:
| id | r | oid |
|----|----|-----|
| 3 | 0 | 2 |
| 6 | 0 | 5 |
Output only the those rows with the preceding good row
SELECT * FROM tbl WHERE A in (
SELECT id FROM tbl WHERE r = 0
UNION
SELECT oid FROM tbl WHERE r = 0
)
OUTPUT:
| id| r |oid|
|---|----|---|
| 2 | 20 | 1 |
| 3 | 0 | 2 |
| 5 | 50 | 4 |
| 6 | 0 | 5 |
Almost works
This is as close as I have got, it does change all the zero's, but it changes them all to the value of the first lookup
UPDATE tbl
SET r = (SELECT r
FROM tbl
WHERE id in (SELECT oid
FROM tbl
WHERE r = 0)
) WHERE r = 0 ;
OUTPUT:
| id| r |oid|
|---|----|---|
| 1 | 10 | 0 |
| 2 | 20 | 1 |
| 3 | 20 | 2 | ** GOOD
| 4 | 40 | 3 |
| 5 | 50 | 4 |
| 6 | 20 | 5 | ** BAD, should be 50
| 7 | 70 | 6 |
| 8 | 80 | 7 |
If it helps, I created this fiddle here that I've been playing with:
http://sqlfiddle.com/#!5/8afff/1
For this sample data all you have to do is use the correct correlated subquery that returns the value of r from the row with id equal to the current oid in the WHERE clause:
UPDATE tbl AS t
SET r = (SELECT tt.r FROM tbl tt WHERE tt.id = t.oid)
WHERE t.r = 0;
See the demo.
I have 3 sets of values i wish to display
Class
Duration
Students
The columns of the tables are as follows:
table 1: class - duration
table 2: class - student
The data would look like this:
table 1:
class - duration
1 - 6
2 - 12
3 - 18
4 - 24
Table 2:
class - student
1 - student 1
2 - student 2
2 - student 3
4 - student 3
the return from the select would look like this:
+-----------+---+----+----+----+
| | 6 | 12 | 18 | 24 |
+-----------+---+----+----+----+
| Student 1 | x | | | |
| Student 2 | | x | | |
| Student 3 | | x | | x |
+-----------+---+----+----+----+
thanks for the ideas!
With known durations, you can pivot data like this:
SELECT *
FROM ( SELECT student
, duration
FROM table1 t
JOIN table2 t2 ON t.class = t2.class )
PIVOT
(
count(duration)
FOR duration IN (6,12,18,24)
)
http://sqlfiddle.com/#!4/a8c7bb/57
Other propositions:
You can create dynamic query to fetch duration and create the list.
You can use PIVOT XML and then extractvalue into readable data
but you will need to know the number of returned columns
I need convert columns to rows in Teradata without TD_UNPIVOT. My table
ID |Code_1 | Code_2 | Code_3 | Code_4|
1 |1000 | 2000 | 3000 | 4000 |
1 |1000 | 2000 | 3000 | NULL |
1 |1000 | 2000 | NULL | NULL |
1 |1000 | NULL | NULL | NULL |
I need to convert Code_1, Code_2, Code_3, Code_4 to 2 columns: first column will have all Code_n (without NULL), second one will have Level of Code:
ID | Code_n | Level_of_Code
1 | 4000 | 4
1 | 3000 | 3
1 | 2000 | 2
1 | 1000 | 1
It means, than I should know when Code has NULL (in which level Code_1, Code_2, Code_3 or Code_4 and after that convert it to columns with numbers of max level where I have not NULL).
Please help me.
Thank you
You can produce rows by using multiple select statements and doing a union all to concatenate them together.
Select id, code_1 as "code_n", 1 as "level_of_code" from your table
Union all
Select id, code_2,2
Union all
Select id, code_3,3
Union all
Select id, code_4,4;
N* [1]| [2] | [3]
1* | 3 | 20 | 3 |
2* | 2 | 10 | 3 |
3* | 3 | 25 | 3 |
4* | 1 | 15 | 3 |
5* | 3 | 30 | 3 |
Can you help me to get a sum of second column, but only sum of elements that has 3 in the first row. For example in that matrix it is 20+25+30=75. In a fastest way (it's actually big matrix).
P.S. I tried something like this with(Train, sum(Column2[,"Date"] == i))
As you can see I need sum Of Colomn2 where date has certain meaning (from 1 to 12)
We can create a logical index with the first column and use that to subset the second column and get the sum
sum(m1[m1[,1]==3,2])
EDIT: Based on #Richard Scriven's comment.
I have a table of values that I want to rotate the values of.
For instance, suppose I have the given (sub) table:
id | value | other columns...
---+-------+---
1 | A | ...
29 | B |
37 | C |
56 | D |
I want to rotate the values so that the final state of the table is:
id | value | other columns...
---+-------+---
1 | B | ...
29 | C |
37 | D |
56 | A |
I know all the ids which should take part in the rotate. However, I'm not sure how I would use this knowledge to update the values. Something like this is not valid SQL:
UPDATE table SET value=('B','C','D','A') WHERE id IN (1,29,37,56)
You could use a CASE expression:
UPDATE MyTable
SET value = CASE id
WHEN 1 THEN 'B'
WHEN 29 THEN 'C'
WHEN 37 THEN 'D'
WHEN 56 THEN 'A'
END
WHERE id IN (1, 29, 37, 56);