result is wrong when retrieving the date - sql

I'm working with PostgreSQL. I have two database tables,i want to get the min and max date stored in table1 daterange column which is of type character varying. table1 and table2 is mapped using sid. i want to get the max and min date range of table1 when compared with sid of table2. Please find the demo here. The result is wrong.
table1:
sid daterange
100 5/25/2017
101 1/24/2017
102 4/4/2014
103 11/12/2007
104 4/24/2012
105 01/15/2017
106 1/1/2017
107 3/11/2016
108 10/10/2001
109 1/10/2016
110 12/12/2016
111 4/24/2017
112 06/28/2015
113 5/24/2017
114 5/22/2017
table2:
sid description
100 success
101 pending
104 pending
105 success
106 success
107 success
110 success
111 pending
112 failed
113 failed
114 pending
Below is my query:
select min(daterange) as minDate,max(daterange) as maxDate from (SELECT to_date(table1.daterange, 'DD/MM/YYYY') as daterange FROM table1,table2 where
table1.sid = table2.sid) tt;
The result is as below which is wrong(mindate and maxdate displayed are wrong dates).
mindate maxdate
2013-12-07 2019-01-07
Please advice. daterange column in table1 is of type character varying.I cannot use ::date to convert to date type, because i need to use this query in my java hibernate code and the java code is not recognizing ::

You have day and month mixed up in the date format string.
Should be
to_date(table1.daterange, 'MM/DD/YYYY')

Related

SQL Query to order data based on other column value

I have the below set of data(current data), where system_id is the ID of the particular system. And pre_system_id's are ID of system where it is dependent. Now I need the order in such a way that rows with no dependent system should come first , then rows with one dependent system come second and so on.
The current result:
System_ID PRE_SYSTEM_ID1 PRE_SYSTEM_ID2 PRE_SYSTEM_ID3 PRE_SYSTEM_ID4
106 100
105
112 105 100 109
100
109 100 105
119 100 109 105 112
102 112 109
104 109 106
The actual result should be like below:
Order System_ID PRE_SYSTEM_ID1 PRE_SYSTEM_ID2 PRE_SYSTEM_ID3 PRE_SYSTEM_ID4
1 100
2 105
3 106 100
4 109 100 105
5 112 105 100 109
6 119 100 109 105 112
7 104 109 106
8 102 112 109 104
The query for the current result is simply
Select * from ImpactedSystem;
Sorting by the various PRE_SYSTEM_IDn columns using the nulls first clause should produce the order you want:
select *
from ImpactedSystem
order by PRE_SYSTEM_ID1 nulls first,
PRE_SYSTEM_ID2 nulls first,
PRE_SYSTEM_ID3 nulls first,
PRE_SYSTEM_ID4 nulls first,
SYSTEM_ID
Finally sort by SYSTEM_ID, to order the values with no dependent IDs.
you can use the below query to obtain the result as well.
select *
from Current_data
order by DECODE(pre_system_td1,null,1),
DECODE(pre_system_td2,null,1),
DECODE(pre_system_td3,null,1),
DECODE(pre_system_td4,null,1);

Need help on Query

Table_Name : Order_trans_detail
Order_id Order_date Order_qty Item_id order_amount
100 12-Jan-16 1 1001 20
101 13-Feb-15 4 1001 80
103 14-Mar-16 3 1001 60
104 16-Dec-15 9 1001 180
105 17-Jan-16 1 1001 20
106 18-Feb-16 4 1001 80
107 19-Feb-16 3 1001 60
108 20-Jan-15 9 1001 180
109 21-Mar-15 3 1001 60
110 21-Apr-15 3 1001 60
Need Query to identify how many orders placed in Month of Feb-2016 as to display Month Name and count.
You need to use DATENAME and YEAR function to extract Month name and Year from date and use it in Group by to get the count
select DATENAME(MONTH,Order_date ),YEAR(Order_date), Count(*)
From Order_trans_detail
Group by DATENAME(MONTH,Order_date ),YEAR
To filter the records add Where clause
Where DATENAME(MONTH,Order_date ) = 'february' and YEAR(Order_date) = 2016
To get the result in Mon-year format use this in Select
DATENAME(MONTH,Order_date )+'-'+cast(YEAR(Order_date) as char(4))
If you are using SQL Server 2012+ to concatenate month and year use CONCAT function
CONCAT(DATENAME(MONTH,Order_date ),'-',YEAR(Order_date))
Advantage of using CONCAT is that you don't need to perform explicit conversion when concatenating Int with Varchar

Getting values for a varying date range in Postgresql

I am trying to get a maximum value from one table using the date range from another table. I am using SQL on a postgresql database. The goal is to get the maximum value for the date range added to the table that has the start and end date (by year and area). I see this as two steps outlined below.
Step One: I am looking to use two columns that are dates in Table1 to create a range. The table has these columns:
ID (integer(11))
Date1 (varchar(10))
Date2 (varchar(10))
Year (integer)
Area (varchar)
Here is some sample data from Table1:
ID Date1 Date2 Year Area
101 8/21/2000 11/20/2000 2000 5
102 7/31/2000 10/30/2000 2000 5
103 7/10/2000 10/9/2000 2000 6
104 7/10/2000 10/9/2000 2000 6
105 7/4/2000 10/3/2000 2000 6
106 7/10/2000 10/9/2000 2000 6
107 7/31/2000 10/30/2000 2000 7
108 7/31/2000 10/30/2000 2000 7
Step Two: Pull the maximum value from Table2 based on the varying date range from Date1 to Date2 in Table1. Table2 has these values:
Date (varchar(12))
Area (varchar(11))
Value (varchar(6))
Here is some (very limited) sample data from Table2:
Date Area Value
8/2/2000 5 72.1
8/25/2000 5 68.4
9/14/2000 5 53.3
7/5/2000 6 47.9
8/1/2000 6 10.2
9/30/2000 6 11.6
8/5/2000 7 35.2
9/1/2000 7 45.4
So in the end I would like a modified Table1 that adds the Max_Value for the date range (pulled from Table2) and looks like this:
ID Date1 Date2 Year Area Max_Value
101 8/21/2000 11/20/2000 2000 5 68.4
102 7/31/2000 10/30/2000 2000 5 72.1
103 7/10/2000 10/9/2000 2000 6 11.6
104 7/10/2000 10/9/2000 2000 6 11.6
105 7/4/2000 10/3/2000 2000 6 47.9
106 7/10/2000 10/9/2000 2000 6 11.6
107 7/31/2000 10/30/2000 2000 7 45.4
108 7/31/2000 10/30/2000 2000 7 45.4
Thanks for any help in advance.
You can do this in several ways. One method would use join with an explicit aggregation. However, because you only want one column, I think a correlated subquery is simpler to code:
select t1.*,
(select max(t2.value)
from table2 t2
where t2.date between t1.date1 and t1.date2
) as maxvalue
from table1 t1;

ORACLE SQL Select timestamps column from table. Producing more results than intended

Hello currently I have a working script below. I am using Oracle 10
SELECT z.no as "ID_One",
MAX(r.value) as "Max",
round(MAX(r.value)/80000,2) as "ROUND"
FROM Table1 r, Table2 z
WHERE r.timestamp > ((SYSDATE - TO_DATE('01/01/1970 00:00:00', 'MM-DD-YYYY HH24:MI:SS')) * 24 * 60 * 60) - 80000
AND r.va=21
AND r.nor IN ('7','98','3','3')
AND r.nor = z.re
GROUP BY r.nor, r.varr, z.no;
It produces a table like this
ID_ONE MAX ROUND
105 500 232
106 232 32
333 23 .21
444 34 .321
I want to select a row call timestamp from table r. However when I add " r.timestamp " in to my query it produces 500 rows of data instead of 4. It looks like it is producing the the highest number for each timestamp instead. How would I produce a table that looks like this ? fyi timestamp column is in unix time. I can do the conversion myself. I just need to know how to get out these rows.
ID_ONE MAX ROUND TIMESTAMP
105 500 232 DEC 21,2021 10:00
106 232 32 DEC 21,2021 23:12
333 23 .21 DEC 31,2021 2:12
444 34 .321 DEC 31,2021 23:12
When I add the column time stamp it does not create what is above. What I am getting instead is something like that looks like this the other two ids are below in this 500 long row of data. I only wanted the 4 that is the highest value (MAX) from this set of time. ID_ONE is my id for a stock of inventory for a warehouse.
ID_ONE ROUND TIMESTAMP MAX
106 338
.06 1406694567
106 355
.06 1406696037
106 246
.04 1406696337
106 363
.06 1406700687
106 330
.06 1406700987
106 512
.09 1406701347
106 459
.08 1406704047
106 427
.07 1406711038
106 596
.1 1406713111
106 401
.07 1406715872
106 682
.11 1406726192
106 2776
.46 1406726492
105 414
.07 1406728863
105 380
.06 1406734055
105 378
.06 1406734655
105 722
.12 1406735555
105 144
.02 1406665697
105 5
I have edited my answer kindly try the below
SELECT z.no as "ID_One",
max(r.value) as "Max",
round(MAX(r.value)/80000,2) as "ROUND",r.Timestamp
FROM Table1 r, Table2 z
where r.timestamp > ((SYSDATE - TO_DATE ('01/01/1970 00:00:00', 'MM
-DD-YYYY HH24:MI:SS')) * 24 * 60 * 60) - 80000
and r.va=21
AND r.nor IN ('7','98','3','3')
AND r.value=(select max(r1.value) from Table1 r1 where r1.va=r.va and r1.nor=r.nor)
AND r.nor = z.re group by r.nor, r.varr, z.no;
This looks like an ideal use case for analytic functions:
SELECT
v1.*,
round(v1.value/80000,2) as rounded_max_value
FROM (
SELECT
z.no as id_one,
r.value,
row_number() over (partition by r.nor, r.varr, z.no order by r.value desc) as rn,
r.timestamp
FROM Table1 r, Table2 z
WHERE r.timestamp >
((SYSDATE - TO_DATE('01/01/1970 00:00:00', 'MM-DD-YYYY HH24:MI:SS')) * 24 * 60 * 60) - 80000
AND r.va=21
AND r.nor IN ('7','98','3','3')
AND r.nor = z.re
) v1
where v1.rn = 1
This query
uses row_number over (partition by .. order by ) to get an ordering of the rows within a group
uses rn = 1 in the outer query to get only the row having the maximum value
Some additional recommendations:
if your r.nor column is numeric, then don't use string literals; use IN (7,98,3,3) instead (BTW: why do you have 3 twice in your IN list?
don't use " for column aliases unless absolutely necessary (since it makes them case-sensitive) ; they are a PITA
don't put your JOIN conditions into the WHERE clause; it makes your query harder to read. Use ANSI style joins instead.

For Each Loop in SQL Server using Cursor

I have a table with 4 cols.
HouseNo, Date, Time and Temp.
I have managed to obtain the different HouseNos in a separate table. Now i want to insert all the dates for all the house nos.
Sample Data from table. There are like a few million rows like this.
HouseNo Date Time Temp
102 1/1/2010 10:00 67
102 2/1/2010 10:00 73
102 3/1/2010 10:00 75
103 1/1/2010 10:00 69
103 2/1/2010 10:00 63
104 1/1/2010 10:00 71
104 2/1/2010 10:00 12
Expected Output is
table 1
102 1/1/2010
102 2/1/2010
102 3/1/2010
table 2
103 1/1/2010
103 2/1/2010
table 3
104 1/1/2010
104 2/1/2010
Then i want to be able to loop through each row in the tables derieved to perform some operation on the temperature field.
If you have one ON/OFF pair per day and the OFF is always before the ON, this gets you the duration.
SELECT
HouseNo,
Date,
DATEDIFF(s,
MIN(CASE WHEN Relay='OFF' THEN Time ELSE NULL END),
MIN(CASE WHEN Relay='ON' THEN Time ELSE NULL END)
) As OffDuration
FROM YourTable
GROUP BY HouseNo, Date
But any normal real life dataset will have multiple ON/OFF pairs. Can you give more detail?
something like this ?
CREATE TABLE new_table
AS (SELECT * FROM old_table);
you can also put some WHERE part and SELECT