Using the following query, I get data from two tables in the db. But if COL5, is empty, do not display even data of(TABLE1). It should also display other data?
SQLiteDatabase db = mHelper.getReadableDatabase();
final List<Dettaglio1> dettagli1 = new ArrayList<Dettaglio1>();
String sql = "SELECT C._id, " +
"B.col1, " +
"B.col2, " +
"B.col3, " +
"B.col4, " +
"B.col5, " +
"B.col6, " +
"SUM(C.col01), " +
"C.col02, " +
"C.col03 " +
"FROM table1 B LEFT JOIN table2 C ON (B.col5 = C.col02)";
Cursor cur = db.rawQuery(tabella_conti, null);
while (cur.moveToNext()){
Dettaglio1 d01 = new Dettaglio1();
d01.id= cur.getString(0);
d01.col1= cur.getString(1);
d01.col2= cur.getDouble(2);
d01.col3= cur.getString(3);
d01.col4 = cur.getString(4);
d01.col5= cur.getString(5);
d01.col6 = cur.getString(6);
d01.col01 = cur.getDouble(7);
d01.col02 = cur.getString(8);
d01.col03= cur.getString(9);
dettagli1.add(d01);
}
cur.close();
db.close();
....
....
}
If you want to include NULL values you should use LEFT or RIGHT join like this:
... from table1 as B RIGHT JOIN table2 as C ON (B.col5 = C.col02)
If RIGHT join isn't supported on some platforms (thanks to #user3608814, see comments) use LEFT join and change order of tables:
... from table2 as C LEFT JOIN table1 as B ON (C.col02 = B.col5)
UpdateIf this doesn't help (when as you have written there is no data in table2 but you still need results) you should reorganize your data scheme:
Add explicit foreign key to table2 that links it to table1. Let it be table2.extID column. Then it's possible to query like this:
... from table1 as B LEFT JOIN table2 as C ON (B._ID = C.extID)
Related
select new mvp.backend.finance.dto.projection.SplitShipDto(spl.id, spl.promoVolume, spl.baselineVolumeProportion) from SplitShipment spl inner join DateDay spd on spl.dateDay.id = spd.id " +
"where spl.sku.id =:sku_id and spd.day > cast(:date as string)
skuIdAndDates.parallelStream().forEach(spl -> {
float rcpPromo = priceFromSap.getBasePrice() * spl.getPromoVolume();
float rcpBaseline = priceFromSap.getBasePrice() * spl.getBaselineVolumeProportion();
RequestSplitShipmentRCP requestSplitShipmentRCP = RequestSplitShipmentRCP.builder().id(spl.getId()).rcpPromo(rcpPromo).rcpBaseline(rcpBaseline).build();
splitShipmentRCP.add(requestSplitShipmentRCP);
});
update split_shipments set " +
"rcp_promo =:rcpPromo, rcp_baseline =:rcpBaseline " +
"where id =:id
Guys help me. I must use this 2 queries in one query. In first query i select spl.id, spl.promoVolume, spl.baselineVolumeProportion from table split_shipments. How I can creat this? Sorry for my eng...
I have the following code
#Query(nativeQuery = true, value = "select e.* from event e"
+ " join league l on (l.id = e.league_id)"
+ " join sport s on (l.sport_id = s.id)"
+ " join team t1 on (t1.id = e.team_one_id)"
+ " join team t2 on (t2.id = e.team_two_id)"
+ " join country c on (c.id = l.country_id)"
+ " where l.name LIKE %?1%")
Page<Event> getAllEventsFiltered(final PageRequest of, final String filter);
If execute this SQL into database I receive a lot of results but when is executed from java I receive no one result in the same SQL.
I already tried:
where l.name LIKE %?#{escape([1])} escape ?#{escapeCharacter()}
but just works to begins and I needs for both begin and end.
JDBC parameters can only be included in very specific places in a SQL statement. They are not replaced as strings in the SQL statement but they are applied. The specific valid places change from database to database, and also depend on the JDBC driver variant/version.
The general rule is that a parameter can be applied where a single value would be present. String parameters should not be enclosed in single quotes as a VARCHAR would be.
One option to make it compliant, is to place the parameter isolated from other text, for example by using the CONCAT() function. Your query could be rephrased as:
#Query(nativeQuery = true, value = "select e.* from event e"
+ " join league l on (l.id = e.league_id)"
+ " join sport s on (l.sport_id = s.id)"
+ " join team t1 on (t1.id = e.team_one_id)"
+ " join team t2 on (t2.id = e.team_two_id)"
+ " join country c on (c.id = l.country_id)"
+ " where l.name LIKE concat('%', ?1, '%')") // change here
Nevertheless, the specific syntax change can be different depending on the database you are using (that you haven't mentioned).
I have the following code which is used to retrieve data from multiple tables (using joins) and then mapping every row into a DTOList but I also need to apply filters based on user preferences: per table1.name or table2.name, table3, etc.
So I just want to know what would be the best way to do it in terms of performance and best practices;
retrieving all rows and then apply the filters with lambdas (easier)
change the query to a dynamic query with Criteria or something else?
Any other solution=?
#Repository
public class ArchiveRepository {
#Autowired
EntityManager em;
String queryStr = "select wsr.id as sampleid, s.id as slideid, tb.name as batchname, k.lot_number as kitlot, " +
" 'STRING' as slidetype, tb.worklist_name as worklist, wsr.final_call as results, " +
" wa.final_pattern_ids as patterns, 'edited/yesno' as edited, wsr.last_modified_by as user, wsr.last_modified_date as time " +
" from slide s " +
" left join table2 tb on s.test_batch_id = tb.id " +
" left join table3 k on tb.kit_lot_id = k.id " +
" left join table4 w on s.id = w.slide_id " +
" left join tabl5 pw on pw.well_id = w.id " +
" left join tabl6 cw on cw.well_id = w.id " +
" left join tabl7 wsr on wsr.patient_well_sample_id = pw.id or wsr.control_sample_id = cw.id " +
" left join (select * from *** (other subselect)) wa on wa.well_sample_id = wsr.**id or wa.well_sample_id = wsr.**id " +
"where tb.state = 'STATENEEDED'";
public ArchiveDataListDTO getArchiveData(){
Query query = em.createNativeQuery(queryStr);
ArchiveDataListDTO archiveDataListDTO = new ArchiveDataListDTO();
List<Object[]> resultL = (List<Object[]>)query.getResultList();
for( Object[] o : resultL){
archiveDataListDTO.addArchiveDataRow(
new ArchiveDataDTO((String)o[0], String.valueOf(o[1]), (String) o[2], (String) o[3], (String) o[4], (String) o[5],
(String) o[6], (String) o[7], (String) o[8], (String) o[9], (String) o[10]));
}
return archiveDataListDTO;
}
}
**
note I struggled some with the code cause I wanted to apply #sqlresultsetmapping to avoid manual results mapping but it just didn´t work, most of the examples out there are when you have an entity in the DB but in this case I retrieve from many tables.**
Thanks so much
2 .- change the query to a dynamic query with Criteria or something else?
I ended up creating the query on the fly; depending on the filters I get from UI i assemble the query with Java and send it to DB, it´s easier since this required many tables...
I've been researching for quite some time and it seems I may be misunderstanding how inner-joins work in MySQL.
I have 3 tables:
UserTable:
UserID UserName Hash UserUni UserHousing
1 John #123eq.. FK FK
2 Bob !S91ka.. FK FK
...
The foreign keys relate to the following two tables' PKs (UniID and HousingID, respectively):
UniversitiesList:
UniID UniName
1 Yale
2 Penn
...
HousingList:
HousingID HousingName UniID
1 Dorm_1 FK
2 Dorm_2 FK
...
Where, of course, these FKs are PKs (UniID) in Universities list
What I'm trying to do is query the id, hash, UserUni, and UserHousing values, i.e not the keys. This is what I'm playing around with now:
"SELECT UserTable.Hash, UserTable.UserID, UserTable.UserUni, UserTable.UserHousing "
+ "FROM UserTable "
+ "INNER JOIN UniversitiesList "
+ "ON UserTable.UserUni = UniversitiesList.UniID "
+ "INNER JOIN HousingList "
+ "ON UserTable.UserHousing = HousingList.HousingID "
+ "WHERE UserTable.UserName = John"
What I would like to retrieve is something like 1, #123eq, Yale, Dorm_1, but instead I keep getting 1, #123eq, 1, 1.
I'm working with Java so this is how I'm getting the results:
if (result.next()) {
hash = result.getString(1);
id = result.getInt(2);
uni = result.getString(3);
housing = result.getString(4);
}
Any idea one what I'm doing wrong?
Try changing your query to this:
"SELECT UserTable.Hash, UserTable.UserID, UniversitiesList.UniName, HousingList.HousingName "
+ "FROM UserTable "
+ "INNER JOIN UniversitiesList "
+ "ON UserTable.UserUni = UniversitiesList.UniID "
+ "INNER JOIN HousingList "
+ "ON UserTable.UserHousing = HousingList.HousingID "
+ "WHERE UserTable.UserName = John"
As written, you're only asking for the columns in your UserTable, not the other tables. The joins look ok from what I can tell...
I have 3 queries:
// (1)
String sql = "SELECT tblClientInfo.ClientID, tblrefmarket.MarketDesc, tblclientinfo.LastName, tblledger.LoanAmount, "
+ "tblledger.DateStarted, tblledger.DailyPay, tblledger.Expiry FROM tblclientinfo Inner Join tblbusinessinfo ON tblbusinessinfo.ClientID = tblclientinfo.ClientID "
+ "Inner Join tblrefmarket ON tblbusinessinfo.MarketID = tblrefmarket.MarketID "
+ "Inner Join tblledger ON tblledger.ClientID = tblclientinfo.ClientID where MarketDesc = ?";
// (2)
String sumSQL = "SELECT ClientID, sum(tblloanpayment.AmountPaid) as sum FROM tblloanpayment where tblloanpayment.ClientID= ? ";
// (3)
String balSQL = "SELECT (SELECT tblLedger.LoanAmount from tblLedger WHERE tblLedger.ClientID = ?) - (SELECT SUM(tblLoanPayment.AmountPaid) "
+ "FROM tblLoanPayment WHERE tblLoanPayment.ClientID = ?) as balance FROM dual; ";
I have executed this 3 queries to display informations on a jTable. And it was successful.
Now my problem is when I am generating the report (or print) using JasperReports.
I can only display the 1st query since it is inside the database. While query 2 and 3 are not. They are just computations of the payments made in query 1.
How can I join this so that I can be able to display all necessary informations?
Here's my code:
private void cmdPrintActionPerformed(java.awt.event.ActionEvent evt) {
int row = tableMarket.getSelectedRow();
try {
JasperDesign jasperDesign = JRXmlLoader.load("notes receivables.jrxml");
String sql = "SELECT tblClientInfo.ClientID, tblrefmarket.MarketDesc, tblclientinfo.LastName, tblledger.LoanAmount, "
+ "tblledger.DateStarted, tblledger.DailyPay, tblledger.Expiry FROM tblclientinfo Inner Join tblbusinessinfo ON tblbusinessinfo.ClientID = tblclientinfo.ClientID "
+ "Inner Join tblrefmarket ON tblbusinessinfo.MarketID = tblrefmarket.MarketID "
+ "Inner Join tblledger ON tblledger.ClientID = tblclientinfo.ClientID where MarketDesc = '" + tableMarket.getModel().getValueAt(row, 0).toString() + "'";
JRDesignQuery newQuery = new JRDesignQuery();
newQuery.setText(sql);
jasperDesign.setQuery(newQuery);
JasperReport jasperReport = JasperCompileManager.compileReport(jasperDesign);
JasperPrint jasperPrint = JasperFillManager.fillReport(jasperReport, null, conn);
JasperViewer.viewReport(jasperPrint);
} catch (Exception e) {
e.printStackTrace();
JOptionPane.showMessageDialog(null, e);
}
}
This code displays only the first query.
You are already selecting tblLedger.LoanAmount in your first query, so the only additional information required from both your second and third queries is sum(tblloanpayment.AmountPaid). Try:
SELECT c.ClientID,
m.MarketDesc,
c.LastName,
l.LoanAmount,
l.DateStarted,
l.DailyPay,
l.Expiry,
s.sumPaid,
l.LoanAmount - s.sumPaid as balance
FROM tblclientinfo c
Inner Join tblbusinessinfo b ON b.ClientID = c.ClientID
Inner Join tblrefmarket m ON b.MarketID = m.MarketID
Inner Join tblledger l ON l.ClientID = c.ClientID
left join (SELECT ClientID, sum(AmountPaid) as sumPaid
FROM tblloanpayment group by ClientID) s on c.ClientID = s.ClientID
where m.MarketDesc = ?
Remove the restriction by client id in the second and third queries. Make them into subselects (that is, put them in parentheses) and make a big select that joins all three subselects on client id.
Edit
So if the three queries are query1, query2, query3, you'd end up with
select ... from (query1) baseSql
join (query2) sumSql on baseSql.clientId = sumSql.clientId
join (query3) balSql on baseSql.clientId = balSql.clientId
You may need to use left join instead of join if there are rows in baseSql that are missing from sumSql or balSql.