how to get column name from database in R - mysql

I'm using sqldf to get some column from table in database, but the result doesn't show the column name, which is I just get the contents.
My code is following as:
z<-sqldf("select (gid, longitude, latitude, acq_date) from kalimantan limit 10" )
and the result
row 1
(1,112.544000000000000,-2.145000000000000,39448) 2
(2,111.617000000000000,-2.720000000000000,39448) 3
(3,110.277000000000000,-2.554000000000000,39448) 4
(4,117.037000000000010,-0.553000000000000,39449) 5
(5,117.583000000000000,-0.462000000000000,39454) 6
(6,110.292000000000000,-1.517000000000000,39455) 7
(7,111.517000000000000,-2.399000000000000,39455) 8
(8,110.285000000000000,-2.660000000000000,39455) 9
(9,109.527000000000000,-0.219000000000000,39455) 10
(10,110.756000000000000,-2.727000000000000,39457)
What I need is
gid | longitude | latitude | date
1 112.544000000000000 -2.145000000000000,39448) 1
2 111.617000000000000 -2.720000000000000,39448) 2
3 110.277000000000000 -2.554000000000000,39448) 3
4 117.037000000000010 -0.553000000000000,39449) 4
5 117.583000000000000 -0.462000000000000,39454) 5
6 110.292000000000000 -1.517000000000000,39455) 6
7 111.517000000000000 -2.399000000000000,39455) 7
8 110.285000000000000 -2.660000000000000,39455) 8
9 109.527000000000000 -0.219000000000000,39455) 9
10 110.756000000000000 -2.727000000000000,39457) 10

Related

How to add column in table grouped by value and max value in date column using sql query?

I have a table:
id date val
1 10.08.2022 10
1 12.08.2022 11
1 08.08.2022 15
1 16.08.2022 9
2 02.07.2022 2
2 01.07.2022 4
2 30.07.2022 7
I want to create two new columns last_v and max_v which are equal to last val for each id by date and maximum val per id. So desired output is:
id date val last_v max_v
1 10.08.2022 10 9 15
1 12.08.2022 11 9 15
1 08.08.2022 15 9 15
1 16.08.2022 9 9 15
2 02.07.2022 2 2 7
2 01.07.2022 4 2 7
2 30.06.2022 7 2 7
How could I do that?
You can use window functions!
select t.*,
first_value(val) over(partition by id order by dt desc) last_val,
max(val) over(partition by id) max_val
from mytable t
Demo on DB Fiddle:
id
dt
val
last_val
max_val
1
2022-08-08
15
9
15
1
2022-08-10
10
9
15
1
2022-08-12
11
9
15
1
2022-08-16
9
9
15
2
2022-06-30
7
2
7
2
2022-07-01
4
2
7
2
2022-07-02
2
2
7

calculating the average of marks from the beginning to this record

i have a table named test with the below structure like this
id mark join_id
1 5 1
2 4 1
3 9 1
4 5 2
5 7 2
6 12 2
i want to write a query that can get me the average of the marks from the beginning record to this record with the desired result as below
id mark join_id avg_of_previous_marks
1 5 1 5
2 4 1 4.5
3 9 1 6
4 5 2 5.75
5 7 2 6
6 12 2 7
i wrote this query but it doesn't seem to work correctly
SELECT test.id, test.mark, test.join_id, test_avg.avg_of_previous_marks FROM test
LEFT JOIN (SELECT id, join_id, AVG(mark) as avg_of_previous_marks FROM test GROUP BY
join_id) test_avg
ON test_avg.join_id = test.join_id AND test_avg.id <= test.id
and it gives this resault
id mark join_id avg_of_previous_marks
1 5 1 6
2 4 1 6
3 9 1 6
4 5 2 8
5 7 2 8
6 12 2 8
Its a simple running total that you need.
select id,mark,join_id, avg(mark) over (order by id) avg_of_previous_marks from test_avg ;
fiddle here

Fast way to combine multiple rows in mysql

I've tried an sql-query like this:
SELECT A.id, FROM_UNIXTIME(A.timestamp) AS timestamp, A.test, B.test2, B.test3, C.test4
FROM table AS A
INNER JOIN table AS B
ON A.id = B.id - 3
INNER JOIN table AS C
ON A.id = C.id - 6
ORDER BY id DESC
To merge different rows from one table together.
But it is very slow. Is there an way to speed it up in MySQL itself. I want to create an view to select the data from tableau (tableau itself has no preprocessing).
With an postprocessing script it would be very easy (just save up to six old columns and read it back six rows later). Shouldn't such an easy task possible with SQL too?
Example:
Original Table
id
timestamp
test
test2
test3
test4
1
…
1
1
1
1
2
…
2
2
2
2
3
…
3
3
3
3
4
…
4
4
4
4
5
…
5
5
5
5
6
…
6
6
6
6
7
…
7
7
7
7
8
…
8
8
8
8
9
…
9
9
9
9
10
…
10
10
10
10
11
…
11
11
11
11
12
…
12
12
12
12
13
…
13
13
13
13
Needed result:
id
timestamp
test
test2
test3
test4
1
…
1
null
null
null
2
…
2
null
null
null
3
…
3
null
null
null
4
…
4
1
1
null
5
…
5
2
2
null
6
…
6
3
3
null
7
…
7
4
4
null
8
…
8
5
5
1
9
…
9
6
6
2
10
…
10
7
7
3
11
…
11
8
8
4
12
…
12
9
9
5
13
…
13
10
10
6
ID is an unique autoincrement value.

Query with CASE statement in Group By I need to create an entry where no results occur in the WHEN

I have a query which groups up incoming payments into date ranges (1-7 days, 3-6 months etc.) and it largely works as I had hoped. However, I want to return a row which says 0 when no income is expected in the date range.
The group by looks like this:
group by
CASE WHEN timestampdiff(day,curdate(),data.duedate) between 0 and 7 then 1
WHEN timestampdiff(day,curdate(),data.duedate) between 8 and 14 then 2
WHEN timestampdiff(day,curdate(),data.duedate) between 15 and 30 then 3
WHEN timestampdiff(month,curdate(),data.duedate) between 1 and 2 then 4
WHEN timestampdiff(month,curdate(),data.duedate) between 2 and 3 then 5
WHEN timestampdiff(month,curdate(),data.duedate) between 3 and 6 then 6
WHEN timestampdiff(month,curdate(),data.duedate) between 6 and 12 then 7
WHEN timestampdiff(year,curdate(),data.duedate) between 1 and 2 then 8
WHEN timestampdiff(year,curdate(),data.duedate) between 2 and 3 then 9
WHEN timestampdiff(year,curdate(),data.duedate) between 3 and 4 then 10
WHEN timestampdiff(year,curdate(),data.duedate) between 5 and 6 then 11
WHEN timestampdiff(year,curdate(),data.duedate) >= 7 then 12
This works correctly in that it will give me the correct amounts, but I want to force the code to give me a 0. So I currently get this:
1 300000
5 150000
8 300000
What I actually want is this:
1 300000
2 0
3 0
4 0
5 150000
6 0
7 0
8 300000
etc.
This is the entire query - I've tried using an IFNULL() but had no success:
select
sum(data.principaldue+data.interestdue) as m
from
(select
la.id
,rep.duedate
,rep.PRINCIPALDUE
,rep.INTERESTDUE
from repayment rep
join loanaccount la on la.ENCODEDKEY = rep.PARENTACCOUNTKEY
join loanproduct lp on lp.ENCODEDKEY = la.PRODUCTTYPEKEY
group by
CASE WHEN timestampdiff(day,curdate(),data.duedate) between 0 and 7 then 1
WHEN timestampdiff(day,curdate(),data.duedate) between 8 and 14 then 2
WHEN timestampdiff(day,curdate(),data.duedate) between 15 and 30 then 3
WHEN timestampdiff(month,curdate(),data.duedate) between 1 and 2 then 4
WHEN timestampdiff(month,curdate(),data.duedate) between 2 and 3 then 5
WHEN timestampdiff(month,curdate(),data.duedate) between 3 and 6 then 6
WHEN timestampdiff(month,curdate(),data.duedate) between 6 and 12 then 7
WHEN timestampdiff(year,curdate(),data.duedate) between 1 and 2 then 8
WHEN timestampdiff(year,curdate(),data.duedate) between 2 and 3 then 9
WHEN timestampdiff(year,curdate(),data.duedate) between 3 and 4 then 10
WHEN timestampdiff(year,curdate(),data.duedate) between 5 and 6 then 11
WHEN timestampdiff(year,curdate(),data.duedate) >= 7 then 12
END
Order by
CASE WHEN timestampdiff(day,curdate(),data.duedate) between 0 and 7 then 1
WHEN timestampdiff(day,curdate(),data.duedate) between 8 and 14 then 2
WHEN timestampdiff(day,curdate(),data.duedate) between 15 and 30 then 3
WHEN timestampdiff(month,curdate(),data.duedate) between 1 and 2 then 4
WHEN timestampdiff(month,curdate(),data.duedate) between 2 and 3 then 5
WHEN timestampdiff(month,curdate(),data.duedate) between 3 and 6 then 6
WHEN timestampdiff(month,curdate(),data.duedate) between 6 and 12 then 7
WHEN timestampdiff(year,curdate(),data.duedate) between 1 and 2 then 8
WHEN timestampdiff(year,curdate(),data.duedate) between 2 and 3 then 9
WHEN timestampdiff(year,curdate(),data.duedate) between 3 and 4 then 10
WHEN timestampdiff(year,curdate(),data.duedate) between 5 and 6 then 11
WHEN timestampdiff(year,curdate(),data.duedate) >= 7 then 12
END
This is not a complete answer, but would be too big for comments;
A temporary table with numbers could be useful:
MySql temporary tables:
CREATE TEMPORARY TABLE TempTable (num int);
INSERT INTO TmpTable VALUES(1,2,3,4,5,6,7,8,9,10,11,12 ...);
Then you could right join on this table to make sure missing values are included.
Lets say you have this:
results(num, val):
1 300000
5 150000
8 300000
This should result in your desired output:
SELECT numbers.num, COALESCE(results.val, 0) as val
FROM results RIGHT JOIN TempTable numbers on results.num = numbers.num
WHERE numbers.num <= 12 --or other max number
1 300000
2 0
...
5 150000
...
Hope this helps.
Edit:
If you don't have permission to create temporary tables, look for a workaround to select consecutive integers, for example:
SELECT #row := #row + 1 as row, t.*
FROM some_table t, (SELECT #row := 0) r
Where some_table is any table with enough rows.
Probably use a top N on that.
Another dirty workaround, might be good enough if you don't need many numbers:
SELECT 1 num
UNION
SELECT 2 num
UNION
...
Edit:
Slightly tidier workaround:
SELECT * FROM (VALUES (1), (2), (3), ... ) x(i)

Finding continuous data from a table for months

I have a table which has month data in INT April=4, May=5 and so on. I want those records which have continuous data. My table is as follows. So if a record has discontinuous data, it should not be returned.
Continuous data means those records which having continuous four month. If records are there for 4,5,6,7 or 5,6,7,8 or 6,7,8,9 months then that record should come in result of a ID. If there records for a ID has 4,5,8,9 in month field this is discontinue data for me.
Initial query:
select ID, month from table1 where month in (4,5,6,7,8,9) group by month;
Initial Data:
PK ID month value
1 1 4 400
2 1 5 200
3 1 6 300
4 1 7 400
5 2 5 400
6 2 6 200
7 2 7 100
8 2 8 400
9 3 4 200
10 4 5 800
11 5 6 800
12 5 7 100
13 5 8 700
14 5 9 900
15 6 4 100
16 6 5 200
17 6 8 500
18 6 9 600
Result:
PK ID month value
1 1 4 400
2 1 5 200
3 1 6 300
4 1 7 400
5 2 5 400
6 2 6 200
7 2 7 100
8 2 8 400
11 5 6 800
12 5 7 100
13 5 8 700
14 5 9 900
My database is MySQL.
I have months from April(4) to Sept(9)
Try the below query this will work I hope!
SELECT ID, Month
FROM table1 WHERE month in (4,5,6,7,8,9)
GROUP BY ID, Month
HAVING count(ID)>3
kindly let me know this is working or not