I'm trying to execute the following query:
String query = "select NUMERO_CHAUFFEUR, avg(DISTANCE) as DISTANCE " +
"from " +
"(select NUMERO_CHAUFFEUR, " +
"6387.7 * ACOS((sin(LATITUDE_DEPART / 57.29577951) * SIN(LATITUDE_ARRIVEE / 57.29577951)) + " +
"(COS(LATITUDE_DEPART / 57.29577951) * COS(LATITUDE_ARRIVEE / 57.29577951) * " +
"COS(LONGITUDE_ARRIVEE / 57.29577951 - LONGITUDE_DEPART / 57.29577951))) as DISTANCE " +
"from " +
"(select l.NUMERO_CHAUFFEUR, " +
"regexp_substr(d1.COORDONNEES, '^[^,]+') as LATITUDE_DEPART, " +
"trim(leading ',' FROM regexp_substr(d1.COORDONNEES, ',.*$')) AS LONGITUDE_DEPART, " +
"regexp_substr(d2.COORDONNEES, '^[^,]+') as LATITUDE_ARRIVEE, " +
"trim(leading ',' FROM regexp_substr(d2.COORDONNEES, ',.*$')) AS LONGITUDE_ARRIVEE " +
"from LIVRAISONS l " +
"inner join DEPOTS d1 on(l.NUMERO_DEPOT_DEPART = d1.NUMERO_DEPOT) " +
"inner join DEPOTS d2 on(l.NUMERO_DEPOT_ARRIVE = d2.NUMERO_DEPOT) " +
")) " +
"group by (NUMERO_CHAUFFEUR)";
But a java.sql.SQLException: ORA-01722: invalid number is being thrown. Does anyone know why? Because if I execute the query directly in sql using sqlplus it works fine.
Result of execution of the query using sqlplus:
NUMERO_CHAUFFEUR AVG(DISTANCE)
---------------- -------------
1 507.064894
2 703.326572
5 846.966137
4 511.914202
I've tried the following but the error still persists:
String query = "select NUMERO_CHAUFFEUR, avg(DISTANCE) as DISTANCE " +
"from " +
"(select NUMERO_CHAUFFEUR, " +
"to_number('6387.7') * ACOS((sin(LATITUDE_DEPART / to_number('57.29577951')) * SIN(LATITUDE_ARRIVEE / to_number('57.29577951'))) + " +
"(COS(LATITUDE_DEPART / to_number('57.29577951')) * COS(LATITUDE_ARRIVEE / to_number('57.29577951')) * " +
"COS(LONGITUDE_ARRIVEE / to_number('57.29577951') - LONGITUDE_DEPART / to_number('57.29577951')))) as DISTANCE " +
"from " +
"(select l.NUMERO_CHAUFFEUR, " +
"to_number(regexp_substr(d1.COORDONNEES, '^[^,]+')) as LATITUDE_DEPART, " +
"to_number(trim(leading ',' FROM to_number(regexp_substr(d1.COORDONNEES, ',.*$')))) AS LONGITUDE_DEPART, " +
"to_number(regexp_substr(d2.COORDONNEES, '^[^,]+')) as LATITUDE_ARRIVEE, " +
"to_number(trim(leading ',' FROM to_number(regexp_substr(d2.COORDONNEES, ',.*$')))) AS LONGITUDE_ARRIVEE " +
"from LIVRAISONS l " +
"inner join DEPOTS d1 on(l.NUMERO_DEPOT_DEPART = d1.NUMERO_DEPOT) " +
"inner join DEPOTS d2 on(l.NUMERO_DEPOT_ARRIVE = d2.NUMERO_DEPOT) " +
")) " +
"group by (NUMERO_CHAUFFEUR)";
An ORA-01722 error occurs when an attempt is made to convert a character string into a number, and the string cannot be converted into a number.
regexp_substr would return string and you called it as LATITUDE_DEPART, then you do mathematics with that value which is not correct. you should first convert it as number. this might help you:
TO_NUMBER(regexp_substr(d1.COORDONNEES, '^[^,]')) LATITUDE_DEPART
Do this for all same parts.
Related
In my SpringBoot project I have CrudRepository with next method:
public interface LoanRequestRepository extends CrudRepository<LoanRequest, UUID> {
#Query(
value = "select " +
"lr.id as id," +
"lr.state as state," +
"lr.iban as iban," +
"lr.amount as amount," +
"lr.rate as rate," +
"lr.term as term," +
"lr.best_offer as best_offer," +
"lr.contract_number as contract_number," +
"lr.created as created," +
"lr.company_id as company_id," +
"lr.closed as closed," +
"lr.loan_colvir_id as loan_colvir_id," +
"lr.contract_date as contract_date," +
"lr.first_payment_date as first_payment_date, " +
"lr.gesv as gesv, " +
"c.id as comp_id," +
"c.name as comp_name," +
"c.bin as comp_bin," +
"c.colvir_id as comp_colvir_id," +
"c.kod as comp_kod," +
"c.type as comp_type," +
"c.location_address as comp_location_address," +
"c.registration_address as comp_registration_address," +
"c.legal_address as comp_legal_address," +
"c.actual_address as comp_actual_address," +
"c.department_code as comp_department_code," +
"c.department_name as comp_department_name," +
"c.resident as comp_resident," +
"c.created as comp_created," +
"c.registration_date as comp_registration_date," +
"c.economic_sector as comp_economic_sector," +
"c.short_name as comp_short_name," +
"c.colvir_reference_id as comp_colvir_reference_id," +
"c.card_system_id as comp_card_system_id," +
"c.initial_registration as comp_initial_registration " +
"from loan_request lr " +
"left join company c on c.id = lr.company_id " +
"where 1=1 " +
"and case when :amount is not null " +
" then lr.amount = :amount " +
" else 1=1 end " +
"and case when cast(:dateFrom as date) is not null " +
" then lr.created >= cast(:dateFrom as date)" +
" else 1=1 end " +
"and case when cast(:dateTo as date) is not null " +
" then lr.created <= cast(:dateTo as date) " +
" else 1=1 end " +
"and case when :bin is not null " +
" then c.bin like concat('%', :bin, '%') " +
" else 1=1 end " +
"and case when :companyName is not null " +
" then lower(c.name) like lower(concat('%', :companyName, '%')) " +
" else 1=1 end " +
" group by lr.id, c.id " +
"order by " +
" CASE WHEN :isAscending = true THEN :orderBy END ASC, " +
" CASE WHEN :isAscending = false THEN :orderBy END DESC " +
"limit :size offset :page;")
Iterable<LoanRequestDto> findAllLoanRequestDtoByFilters(#Param("dateFrom") LocalDate dateFrom,
#Param("dateTo") LocalDate dateTo,
#Param("bin") String bin,
#Param("amount") BigDecimal amount,
#Param("companyName") String companyName,
#Param("page") Integer page,
#Param("size") Integer size,
#Param("orderBy") String orderBy,
#Param("isAscending") Boolean isAscending);
}
All query works well, but it ignores "order by" with case expression and list comes in inordered way. I am sending values as "lr.iban", "c.name" to orderBy parameter, and if translate it to sql, it works. But in JPQL it does not work.
So, where am I wrong? How can I solve it?
Also, if change last part with CASE expression to the next:
order by CASE WHEN :isAscending = true THEN c.name END ASC
It also works, well in JPQL. List comes in ordered way.
i have small problem, i googled it many times but i couldn't get it...
i'm using a query (sqlite) to retrieve some data ..
in this query their is Date() used to increase certain date dynamic number of days (coming from column in the same table) ..
if i put this days static (1,2,3,.....) it works fine but if i put column name it doesn't.
this query fails and i want it to work:
String selectQuery = "SELECT DISTINCT * FROM " + TABLE_NAME + " WHERE "
+ DATE + " = date('" + targetDate + "',' " + REPETITIONS + " day') ";
this works fine :
String selectQuery = "SELECT DISTINCT * FROM " + TABLE_NAME + " WHERE "
+ DATE + " = date('" + targetDate + "','2 day') ";
where
targetDate: date entered by user to get events of that date
DATE: date of every event in the table
REPETETIONS: dynamic number (column in the same table)
the problem is using REPETITIONS in the date function...
create statement
String SQL_CREATE_EVENT_TABLE = "CREATE TABLE " + TABLE_NAME + " ( " +
ID + " INTEGER PRIMARY KEY AUTOINCREMENT, " +
TITLE + " TEXT ," +
DATE + " TEXT , " +
IS_NOTIFY + " INTEGER , " +
NOTIFICATION_TIME + " TEXT ," +
REPEAT + " INTEGER ," +
REPEAT_DURATION + " INTEGER ," +
REPETITIONS + " INTEGER ," +
CERTAIN_DATE + " TEXT ," +
NOTE + " TEXT ," +
IS_SPOKEN + " INTEGER " +
" );";
and this is the selecting statement
String selectQuery = "SELECT DISTINCT * FROM " + TABLE_NAME + " WHERE " + DATE + " = '" + targetDate
+ "' OR (( " + REPEAT + " = '1' AND " + REPEAT_DURATION + " = '0' ) AND " + DATE + " <= '" + targetDate + "')"
+ " OR( " + REPEAT + " = '1' AND " + REPEAT_DURATION + " = '3' ) AND " + DATE + " <= '" + targetDate + "' AND " + CERTAIN_DATE + " >= '" + targetDate + "'"
+ " OR (" + REPEAT + " = '1' AND " + REPEAT_DURATION + "= '2' ) AND " + targetDate + " >= '" + DATE + "' AND "+ targetDate+ " <= date('" + DATE + "','" + REPETITIONS + " days')";
The variable REPETITIONS in this statement:
String selectQuery = "SELECT DISTINCT * FROM " + TABLE_NAME + " WHERE "
+ DATE + " = date('" + targetDate + "',' " + REPETITIONS + " day') ";
should be a number and not a column name.
The date function in SQLite has various syntaxes but you use this one:
SELECT date('2014-10-23','+7 day');
you must supply a number before day.
Edit try this:
String selectQuery = "SELECT DISTINCT * FROM " + TABLE_NAME + " WHERE "
+ DATE + " = date('" + targetDate + "', " + REPETITIONS + " || ' day') ";
In sqlite date() function, the NNN days is a string modifier and not an expression. Therefore you cannot use column names or even || string concatenation there.
You can format the modifier string in your code and place it in the SQL. This requires additional query to the database, which is likely not what you want.
If you can assume each day is 24 hours (which is not always true, consider e.g. DST events), you could try something like
... date(strftime('%s', '" + targetDate + "', " + REPETITIONS + "*24*60*60, 'unixepoch') ...
where strftime('%s', ...) converts to seconds and date(..., 'unixepoch') converts back to datestamp.
But seriously I'd consider redesigning the schema to better support your functional requirements.
Could you please help what wrong with this query when calling from Java. When I run the same query in PL/SQL developer it runs perfectly but not when i call from java,.
CRE_DTTM is in DATE datatype
String query4="SELECT NVL(SUM(cur_amt),0) FIRST_PAY" +
" FROM ci_ft ft " +
"WHERE sa_id IN "+
" (SELECT sA_id FROM ci_Sa WHERE acct_id='"+acctid.getIdValue()+"' )" +
"AND TRUNC(crE_dttm)>= (SELECT MAX(crE_Dttm) FROM ci_bill" +
" WHERE accT_id='"+acctid.getIdValue()+"' AND crE_dttm<= (SELECT add_months(To_Date('2016-03-10','YYYY-MM-DD'), -1) FROM dual ) )" +
"AND fT_type_flg IN ('PS','PX')AND ft.cRE_dttm <= (" +
" CASE" +
" WHEN ( to_Date(" +
" (SELECT MAX(crE_Dttm)" +
" FROM ci_bill" +
" WHERE accT_id ='"+acctid.getIdValue()+"'" +
" AND crE_dttm < To_Date('2016-03-10','YYYY-MM-DD')" +
" ) , 'YYYY-MM-DD') = to_Date (" +
" (SELECT MAX(crE_Dttm)" +
" FROM ci_bill" +
" WHERE accT_id='"+acctid.getIdValue()+"'" +
" AND crE_dttm<=" +
" (SELECT add_months(To_Date('2016-03-10','YYYY-MM-DD'), -1) FROM dual" +
" ) ) ,'YYYY-MM-DD'))" +
" THEN To_Date('2016-03-10','YYYY-MM-DD')" +
" ELSE" +
" ( SELECT MAX(crE_Dttm)" +
" FROM ci_bill" +
" WHERE accT_id='"+acctid.getIdValue()+"'" +
" AND crE_dttm < To_Date('2016-03-10','YYYY-MM-DD')) " +
" END)";
com.splwg.base.api.sql.PreparedStatement ps4 = createPreparedStatement(query4);
logger.info(ps4);
ps4.execute();
if(!ps4.list().isEmpty())
{
first_pay=new BigDecimal(ps4.list().get(0).get("FIRST_PAY").toString());
logger.info("first_pay=="+first_pay);
}
}
The error is:
ORA-01830: date format picture ends before converting entire input string site:community.oracle.com
Please note the PreparedStatement is from com.splwg.base.api.sql.PreparedStatement
I think you are passing different date formats in your where clause. Please try matching the date format of crE_dttm with To_Date('2016-03-10','YYYY-MM-DD')
e.g. to_date(crE_dttm, 'YYYY-MM-DD') < To_Date('2016-03-10','YYYY-MM-DD')
Thanks
Sabiha
Here is my queries split up that work perfectly fine...
String sqlstatement = "SELECT WBLinkWebsiteID, WBLinkCategoryParentID, WBLinkTitle, WBLinkURL FROM WEBSITECATEGORY_TABLE WHERE WBLinkCategoryID = ?";
String[] args = { CategorySubID };
Part 2
sqlstatement = "SELECT LOCATIONS_TABLE.LocationWebsiteID, "
+ "LOCATIONS_TABLE.locationCity, "
+ "LOCATIONS_TABLE.locationState, "
+ "LOCATIONS_TABLE.locationCountry, LOCATIONS_TABLE.locationType, "
+ "LOCATIONS_TABLE.locationUrl, "
+ "PREF_TABLE.Pref_SavedTitle "
+ "FROM PREF_TABLE INNER JOIN "
+ "LOCATIONS_TABLE ON PREF_TABLE.Pref_LocationID = LOCATIONS_TABLE.LocationID "
+ "WHERE "
+ "PREF_TABLE.Pref_SavedTitle = '" + theSavedPref + "' ORDER BY LOCATIONS_TABLE.locationState, LOCATIONS_TABLE.locationCity";
Now here is my attempt to combine the two instead of just having 2 go in row back to back and burn time/resources...
String NewSqlstatement = "SELECT LOCATIONS_TABLE.LocationWebsiteID, "
+ "LOCATIONS_TABLE.locationCity, "
+ "LOCATIONS_TABLE.locationState, "
+ "LOCATIONS_TABLE.locationCountry, "
+ "LOCATIONS_TABLE.locationUrl, "
+ "LOCATIONS_TABLE.LocationID, "
+ "PREF_TABLE.Pref_SavedTitle, "
+ "WEBSITECATEGORY_TABLE.WBLinkTitle, "
+ "WEBSITECATEGORY_TABLE.WBLinkURL "
+ "FROM PREF_TABLE INNER JOIN "
+ "LOCATIONS_TABLE ON PREF_TABLE.Pref_LocationID = LOCATIONS_TABLE.LocationID "
+ "INNER JOIN WEBSITECATEGORY_TABLE "
+ "ON WEBSITECATEGORY_TABLE.WBLinkWebsiteID = PREF_TABLE.Pref_WebsiteID "
+ "WHERE "
+ "PREF_TABLE.Pref_SavedTitle = '" + theSavedPref + "'";
Now when I try to do my "SINGLE" way it keeps returning the WHOLE database of Locations in the LOCATIONS_TABLE query. It doesn't do just the exact ones I need.
I know the query works, because I have tested it here: http://sqlfiddle.com/#!6/ede97/2
Now I know my example on sqlfiddle is using MS Server 2014, but I assumed the syntax should be pretty much the same since its just standard SELECT with inner joins, but I could be wrong?
Anyone know what I'm doing wrong? Any help is greatly appreciated
EDIT - Fixed the SQLFIDDLE, I put the wrong statement in the example
Aren't you missing your filter on WBLinkCategoryID in the combined query. Shouldn't you have this:
...
+ "INNER JOIN WEBSITECATEGORY_TABLE "
+ "ON WEBSITECATEGORY_TABLE.WBLinkWebsiteID = PREF_TABLE.Pref_WebsiteID "
+ "WHERE "
+ "WEBSITECATEGORY_TABLE.WBLinkCategoryID IN (<value1>,...,<valueN>) AND "
+ "PREF_TABLE.Pref_SavedTitle = '" + theSavedPref + "'";
I have a sample sqlite database that currently has 7 entries which is queried via:
String selectQuery = "SELECT * FROM " + TABLE_TRANSACTIONS + " x " +
"JOIN (SELECT " + KEY_TYPE_ID + ", COUNT(*) count FROM " + TABLE_TRANSACTIONS + " GROUP BY " + KEY_TYPE_ID + " ORDER BY count DESC) y " +
"ON x.type_id = y.type_id " + //type_id vs. KEY_TYPE_ID as alias won't recognize KEY_TYPE_ID
"WHERE x.type_id = " + TagData.TYPE_EXPENSE;
The output is:
Type A = 2500
Type A = 2599
Type B = 45000
Type C = 299
Type C = 2699
Type C = 10000
Type C = 12000
which correctly groups my types by their respective values. However, the ideal output would be:
Type B = 45000
Type C = 24998
Type A = 5099
where each type is then ordered by the sum of each type. Is this possible? If so what else should I be doing in my query? I'm relatively new to SQL and haven't been able to figure this out yet. Thank you in advance for any insight.
EDIT
Based on your input #CL. I now have a more simplified query:
String selectQuery = "SELECT *, SUM(" + KEY_AMOUNT + ") AS amount_sum " +
"FROM " + TABLE_TRANSACTIONS + " " +
"GROUP BY " + KEY_LABEL_ID + " " +
"ORDER BY amount_sum DESC";
which works as expected when I use sqlfiddle at http://www.sqlfiddle.com/#!5/b3615/1 but not when I use the query in Android. In Android, only the most recent entry for each label type is returned. The SUM doesn't seem to actually do its job.
What am I missing here?
Moving the aggregation and ordering into a subquery does not make sense.
If you want to get the count of all expense transactions per type, just use a simple aggregation:
SELECT Type_ID,
COUNT(*) count
FROM TRANSACTIONS
WHERE TYPE_IF = 'TYPE_EXPENSE'
GROUP BY TYPE_ID
ORDER BY count DESC
This is an aggregation query. Fortunately, SQLite supports CTEs, so you can just do something like this:
with t as (
<your query here>
)
select type, sum(value) as sumv
from t
group by type
order by sumv desc;
Even without the with clause, you could just use your query as a subquery.
You would, of course, use the appropriate column names in the query.
#CL. Your response led me down the correct path, for those interested here is the resulting query that achieved what I was after:
String selectQuery = "SELECT " + KEY_LABEL_ID + ", " + " SUM(" + KEY_AMOUNT + ") as total, " + KEY_TYPE_ID + " " +
"FROM (" +
"SELECT " + KEY_LABEL_ID + ", " + KEY_AMOUNT + ", " + KEY_TYPE_ID + " " +
"FROM " + TABLE_TRANSACTIONS + " " +
") as trans_table " +
"WHERE " + KEY_TYPE_ID + " = " + TagData.TYPE_EXPENSE + " " +
"GROUP BY " + KEY_LABEL_ID + " " +
"ORDER BY total DESC";