Hi guys I´m doing a native query for my project using JPA, but i don´t know how can I do a type of if and else
in a where clause, my ?0 can be 4 values: 10,20,30 and 40, when ?0 is 10, 20, 30 I should use CI.QTD <=
and when ?0 is 40, the condition should be >= . How can I do this?
Follow my code with one condition:
SELECT rownum AS id,
x.*
FROM (
SELECT ci.text,
ci.lenght
FROM ci_table CI
WHERE (?0 IS NULL OR ci.qtd <= ?0)
GROUP BY ci.text,
ci.lenght
ORDER BY ci.text) x ,
nativequery = true);
ADD THE QUERY AFTER THE ADJUSTMENT:
#Query(value =
"SELECT rownum as ID, X.* FROM (SELECT " +
" CI.PARAM1 " +
" CI.PARAM2, " +
" CI.PARAM3, " +
" CI.PARAM4, " +
" CI.PARAM5" +
" FROM " +
" CM_PARAMS CI " +
" WHERE " +
" (?1 is null or CI.PARAM6 = ?1) " +
" AND (?2 is null or CI.PARAM7 = ?2) " +
" AND (?3 is null or CI.PARAM8 = ?3) " +
" AND (?4 is null or CI.PARAM9 = ?4) " +
" AND (?5 is null or CI.PARAM10 = ?5) " +
" AND (?6 is null or CI.PARAM11 = ?6) " +
" AND (?7 is null or CI.PARAM12 = ?7) " +
" AND (?8 is null or CI.PARAM13 = ?8) " +
" AND (CASE WHEN ?9 >30 THEN CI.PARAM14 > 30 " +
" CASE WHEN ?9 <31 THEN CI.PARAM15 <= ?9 END) = 1 " +
" GROUP BY " +
" CI.PARAM1, " +
" CI.PARAM2, " +
" CI.PARAM3, " +
" CI.PARAM4, " +
" CI.PARAM5" +
" ORDER BY " +
" CI.PARAM1 ASC) X " , nativeQuery = true)
Try:
SELECT rownum AS id,
x.*
FROM (
SELECT ci.text,
ci.lenght
FROM ci_table CI
WHERE (CASE WHEN ?0 IN (10,20,30) THEN CI.QTD <= ?0
WHEN ?0 = 40 THEN CI.QTD > ?0 END) = 1
GROUP BY ci.text,
ci.lenght
ORDER BY ci.text) x ,
nativequery = true);
Related
Here are the tables
TAGS :
tag_id
tag_name
1
SENT
2
AIRTIME
3
RECEIVED
4
KOPOKOPO
5
RESTAURANT
6
PAID
7
UBER
TRANS_TAG
tag_id
trans_id
1
1
2
1
3
1
4
1
5
1
6
1
1
2
2
2
3
2
4
2
5
2
6
2
The following are default tags (SENT, AIRTIME, RECEIVED, PAID), the rest are not default tags.
The TRANS_TAG table tracks a transaction id and the tags attached to it.
I would like to write a select SQL statement that selects from these two tables and achieves the following result. - it returns a list of all the tags that have been attached to at least one transaction. it then orders them alphabetically but grouped with the default tags first.
This is the desired result
tag_name
AIRTIME
PAID
RECIVED
SENT
KOPOKOPO
RESTAURANT
This is the code that I have so far
String SQL = "SELECT "
+ KEY_TAG_TITLE +
" FROM " + TABLE_TRANS_TAG
+ " INNER JOIN " + TABLE_TAG + " " + "ON " + TABLE_TRANS_TAG + "." + KEY_TRANS_TAG_TAG_ID
+ " = " + TABLE_TAG + "." + KEY_TAG_ID
+ " GROUP BY " + KEY_TAG_TITLE
+ " ORDER BY " + TABLE_TAG + "." + KEY_TAG_TITLE + " ASC, " + TABLE_TAG + "." + KEY_ROW_ID + " ASC";
You can use:
SELECT T.KEY_TAG_TITLE
FROM TABLE_TRANS_TAG TT INNER JOIN
TABLE_TAG T
ON TT.KEY_TRANS_TAG_TAG_ID = T.KEY_TAG_ID
GROUP BY T.KEY_TAG_TITLE
ORDER BY (CASE WHEN T.KEY_TAG_TITLE IN ('SENT', 'AIRTIME', 'RECEIVED', 'PAID') THEN 1 ELSE 2 END),
T.KEY_TAG_TITLE;
Don't use join and aggregation for such a simple requirement.
It would result in poor performance.
Use EXISTS and conditional sorting:
String SQL = "SELECT tg." + KEY_TAG_TITLE + " " +
"FROM " + TABLE_TAG + " AS tg " +
"WHERE EXISTS (SELECT 1 FROM " + TABLE_TRANS_TAG + " AS tr WHERE tr." + KEY_TRANS_TAG_TAG_ID + " = tg." + KEY_TAG_ID + ") " +
"ORDER BY tg." + KEY_TAG_TITLE + " IN ('SENT', 'AIRTIME', 'RECEIVED', 'PAID') DESC, tg." + KEY_TAG_TITLE;
select
ic.item_name,
lh.locn_brcd from_locn,
lh2.locn_brcd to_locn,
wl.from_container,
wl.to_container,
wl.units,
wl.prev_from_container_status prev_from_lpn_status,
wl.curr_from_container_status curr_from_lpn_status,
wl.prev_to_container_status prev_to_lpn_status,
wl.curr_to_container_status curr_to_lpn_status,
wl.work_batch_number,
wl.transaction_name,
wl.action,
wl.work_id,
wl.date_updated,
wl.source_updated,
wl.tote_number,
wl.chute
from m_work_log wl
LEFT join item_cbo ic on wl.item_id=ic.item_id
left join locn_hdr lh on wl.from_location_id = lh.locn_id
left join locn_hdr lh2 on wl.to_location_id = lh2.locn_id
where wl.action in (:action)
and trunc(wl.date_updated) between :start_date and :end_date
and (ic.item_name in (:list) OR
wl.source_updated = :username OR
wl.to_container in (:LPNList) OR
(:list is null and :username is null and :LPNList is null)
)
order by date_updated desc
Hi everyone,
when I run this code through Oracle SQL Developer and I add two items to the :list parameter and two items to the :action parameter it works fine. But when I run this through SSRS (report builder ) it fails to run and I get an "ORA-00920: invalid relational operator". I'm new to SQL and i'm not sure what I am doing incorrectly here. Any help is greatly appreciated. Thanks!
There are 2 ways to do this:
Multiple Value Parameter:
First of all, you must use Oracle provider, multiple value paramaters does not work with neither ODBC nor OLEDB connections (reference).
Here is an external link explaining in detail here.
Using an expression as the query by putting the whole thing like this ="query_here"
="select "
+ " ic.item_name,"
+ " lh.locn_brcd from_locn,"
+ " lh2.locn_brcd to_locn,"
+ " wl.from_container,"
+ " wl.to_container,"
+ " wl.units,"
+ " wl.prev_from_container_status prev_from_lpn_status,"
+ " wl.curr_from_container_status curr_from_lpn_status,"
+ " wl.prev_to_container_status prev_to_lpn_status,"
+ " wl.curr_to_container_status curr_to_lpn_status,"
+ " wl.work_batch_number,"
+ " wl.transaction_name,"
+ " wl.action,"
+ " wl.work_id,"
+ " wl.date_updated,"
+ " wl.source_updated,"
+ " wl.tote_number,"
+ " wl.chute"
+ "from m_work_log wl"
+ " LEFT join item_cbo ic on wl.item_id=ic.item_id"
+ " left join locn_hdr lh on wl.from_location_id = lh.locn_id"
+ " left join locn_hdr lh2 on wl.to_location_id = lh2.locn_id"
+ "where wl.action in (:action)"
+ " and trunc(wl.date_updated) between :start_date and :end_date"
+ " and (ic.item_name in ('" + Join(Parameters!list.Value , "', '")" + ') OR"
+ " wl.source_updated = :username OR"
+ " wl.to_container in ('" + Join(Parameters!LPNList.Value , "', '")" + ') OR"
+ " (:list = '_N/A_' and :username is null and :LPNList = '_N/A_')"
+ " )"
+ " order by date_updated desc"
In this case you will need to provide default empty values to your lists. I used 'N/A' in my example.
I'm trying to join 3 tables in a view; here is my situation:
I have a table that contains Sale it Contain Sale Details For per Item
Another Sale Master A All Sale Details of All Item..
And Another Inventory Details
String query = "SELECT SALE.ITEM_CODE, SALE.ITEM_NAME, SALE.UNIT, "
+ "SALE.QNTY, SALE.AMOUNT, SALE_MASTER.LONGDATE, SALE_MASTER.BILL_NO, "
+ "SALE_MASTER.LEDGER_CODE, SALE_MASTER.LEDGER_NAME FROM SALE "
+ "INNER JOIN SALE_MASTER"
+ " ON SALE.BILL_NO = SALE_MASTER.BILL_NO SALE"
+ "INNER JOIN INVENTORY ON SALE.ITEM_CODE = INVENTORY.ITEM_CODE"
+ "WHERE "+CATORINORG+" LIKE '%"+LIKE+"%' "
+ "AND (SALE_MASTER.LONGDATE >= " + From + " AND SALE_MASTER.LONGDATE <= " + To + ")";
is it right way.. thanks adv
SELECT SALE.ITEM_CODE, SALE.ITEM_NAME, SALE.UNIT, "
+ "SALE.QNTY, SALE.AMOUNT, SALE_MASTER.LONGDATE, SALE_MASTER.BILL_NO, "
+ "SALE_MASTER.LEDGER_CODE, SALE_MASTER.LEDGER_NAME FROM SALE "
+ "INNER JOIN SALE_MASTER"
+ " ON SALE.BILL_NO = SALE_MASTER.BILL_NO"
+ " INNER JOIN INVENTORY ON INVENTORY.ITEM_CODE = SALE.ITEM_CODE"
+ " WHERE "+CATORINORG+" LIKE '%"+LIKE+"%' "
+ "AND (SALE_MASTER.LONGDATE >= " + From + " AND SALE_MASTER.LONGDATE <= " + To + ")
its worked for me
Heres specifically the sql text in a file.
select substr(to_char(ctl.tody_run_dt,'YYYYMMDD'),1,8) tody_yyyymmdd,
substr(to_char(cdr.nxt_proc_dt,'YYYYMMDD'),1,8) nxt_proc_yyyymmdd,
add_months(ctl.tody_run_dt - cdr.past_accru_dys,
- ct.nbr_cycl_for_adj) beg_proc_dt,
from tbl_crd )
and prv.calendar_run_dt =
( select max(calendar_run_dt)
from run_tbl1 prv2
From this i wish to extract all the tables,
This seems pretty complicated to be done through a regexp? Is there a way? Or should i write a program? I just cant come up with an algorithm.
You might be able to do something like a linear search like this. It relaxed for your example
and just targets the from keyword, excludes other keywords.
The table data is captured in group 1. It has to be split appart upon each
match through the find loop.
# from\s+((?!(?:select|from|where|and)\b)\w+(?:[,\s]+(?!(?:select|from|where|and)\b)\w+)*)
from
\s+
( # (1 start), Contains all the table info
(?! # exclude keywords
(?:
select
| from
| where
| and
)
\b
)
\w+
(?:
[,\s]+
(?! # exclude keywords
(?:
select
| from
| where
| and
)
\b
)
\w+
)*
) # (1 end)
Perl test case
$/ = undef;
$str = <DATA>;
while ( $str =~ /from\s+((?!(?:select|from|where|and)\b)\w+(?:[,\s]+(?!(?:select|from|where|and)\b)\w+)*)/g )
{
print "\n'$1'";
}
__DATA__
select substr(to_char(ctl.tody_run_dt,'YYYYMMDD'),1,8) tody_yyyymmdd,
substr(to_char(cdr.nxt_proc_dt,'YYYYMMDD'),1,8) nxt_proc_yyyymmdd,
add_months(ctl.tody_run_dt - cdr.past_accru_dys,
- ct.nbr_cycl_for_adj) beg_proc_dt,
(ctl.tody_run_dt + cdr.futr_accru_dys) end_proc_dt,
ctl.tody_end_proc_dt,
ctl.prv_end_proc_dt,
cdr.fst_proc_dy,
cdr.lst_proc_dy,
cdr.accru_nbr_of_dys,
cdr.dy_of_wk,
from run_tbl1 cdr, runtbl
run_tbl1 prv,
run_tbl_cntl ctl,
tbl_crd ct
where cdr.calendar_run_dt = ctl.tody_run_dt
and ct.nbr_cycl_for_adj =
( select max(nbr_cycl_for_adj)
from tbl_crd )
and prv.calendar_run_dt =
( select max(calendar_run_dt)
from run_tbl1 prv2
where prv2.calendar_run_dt < ctl.tody_run_dt
and prv2.accru_nbr_of_dys = 1 )
and rownum = 1
Output >>
'run_tbl1 cdr, runtbl
run_tbl1 prv,
run_tbl_cntl ctl,
tbl_crd ct'
'tbl_crd'
'run_tbl1 prv2'
First I had to correct some syntax errors within your SQL.
... cdr.dy_of_wk, <<<< the comma is wrong
from run_tbl1 cdr ...
Here the proove of concept using JSQLParser V0.8.9 (https://github.com/JSQLParser/JSqlParser) to extract tablenames.
public static void main(String[] args) throws JSQLParserException {
TablesNamesFinder tfinder = new TablesNamesFinder();
String sql = "select substr(to_char(ctl.tody_run_dt,'YYYYMMDD'),1,8) tody_yyyymmdd, "
+ " substr(to_char(cdr.nxt_proc_dt,'YYYYMMDD'),1,8) nxt_proc_yyyymmdd, "
+ " add_months(ctl.tody_run_dt - cdr.past_accru_dys, "
+ " - ct.nbr_cycl_for_adj) beg_proc_dt, "
+ " (ctl.tody_run_dt + cdr.futr_accru_dys) end_proc_dt, "
+ " ctl.tody_end_proc_dt, "
+ " ctl.prv_end_proc_dt, "
+ " cdr.fst_proc_dy, "
+ " cdr.lst_proc_dy, "
+ " cdr.accru_nbr_of_dys, "
+ " cdr.dy_of_wk "
+ " from run_tbl1 cdr, runtbl, "
+ " run_tbl1 prv, "
+ " run_tbl_cntl ctl, "
+ " tbl_crd ct "
+ " where cdr.calendar_run_dt = ctl.tody_run_dt "
+ " and ct.nbr_cycl_for_adj = "
+ " ( select max(nbr_cycl_for_adj) "
+ " from tbl_crd ) "
+ " and prv.calendar_run_dt = "
+ " ( select max(calendar_run_dt) "
+ " from run_tbl1 prv2 "
+ " where prv2.calendar_run_dt < ctl.tody_run_dt "
+ " and prv2.accru_nbr_of_dys = 1 ) "
+ " and rownum = 1 ";
//parse SQL statement
Select select = (Select) CCJSqlParserUtil.parse(sql);
//extract table names
List<String> tableList = tfinder.getTableList(select);
System.out.println(tableList);
}
and it outputs
[run_tbl1, runtbl, run_tbl_cntl, tbl_crd]
I know similar questions has been before but I just couldn't quite understand them, still very new to SQL and wanting to get the solution as well as understanding why it wouldn't work originally.
sql = "UPDATE e " +
"SET " +
"e.Operator = '" + emp.Operator + "', " +
"e.LoginName = '" + emp.Login + "', " +
"e.Active = " + (emp.Active == true ? 1 : 0) + "," +
"e.Position = '" + emp.Position + "', " +
"p.Admin = " + (emp.Permission.Admin == true ? 1 : 0) + "," +
"p.Manager = " + (emp.Permission.Manager == true ? 1 : 0) + "," +
"p.Overtime = " + (emp.Permission.Overtime == true ? 1 : 0) + "," +
"p.TimeInLieu = " + emp.Permission.TimeInLieu + " " +
"FROM Employee e INNER JOIN Permissions p " +
"ON e.PermissionID = p.PermissionID AND e.Operator = '" + employee + "'";
when trying to execute the command I get this error.
The multi-part identifier "p.Admin" could not be bound.
Any help would be greatly received.