Using Alias While Concating Columns And Running Query Through A Java Program - java

I want to concat two columns and use an alias for the columns while querying.
The query is something like this:
select distinct T1.*,
T1.FieldA || ',' || FieldB from table1 T1
join ( select FieldA || ',' || FieldB as criteria from table2 where
create_dateTime >= to_timestamp('10-NOV-14 01.01.01.000000000 PM','DD-MON-RR HH.MI.SS.FF AM') and
create_dateTime <= to_timestamp('19-NOV-14 01.01.01.000000000 PM','DD-MON-RR HH.MI.SS.FF AM'))
T2 on (T1.FieldA || ',' || FieldB = T2.criteria) ORDER BY T1.FieldA || ',' || FieldB;
This query works for me in Oracle. Would it work in MYSQL, MS SQL, DB2 as well ?
Is there anyother way of writing this query ?

You want to translate this Oracle query to MySQL. First, let's try to optimize it overall. You're joining on a computed field (computed by concatenation). That's bound to be slow. Why not simply join on the fields in the concatenation, like so:
from table1 T1
join table2 T2 ON T1.FieldA = T2.FieldA AND T1.FieldB = T2.FieldB
Now, there may be some complex data-dependent reason this won't work. But I seriously doubt it.
Second, you're using ordinary (INNER) JOIN, so there's no need for the timestamp selection to appear in a subquery. That means your Oracle-specific query can be refactored like this. This is a lot simpler for your dbms to handle.
select distinct
T1.*,
T1.FieldA || ',' || T1.FieldB AS criteria
from table1 T1
join table2 T2 ON T1.FieldA = T2.FieldA AND T1.FieldB = T2.FieldB
where T2.create_dateTime >=
to_timestamp('10-NOV-14 01.01.01.000000000 PM','DD-MON-RR HH.MI.SS.FF AM')
and T2.create_dateTime <=
to_timestamp('19-NOV-14 01.01.01.000000000 PM','DD-MON-RR HH.MI.SS.FF AM')
ORDER BY T1.FieldA || ',' || T1.FieldB;
Try this in your Oracle system. You may be happy at the performance improvement.
Finally, you need to change your concatenations and date processing to be MySQL specific. That's easy enough.
select distinct
T1.*,
CONCAT(T1.FieldA, ',', T1.FieldB) AS criteria
from table1 T1
join table2 T2 ON T1.FieldA = T2.FieldA AND T1.FieldB = T2.FieldB
where T2.create_dateTime >= '2014-11-10 13:01:01'
and T2.create_dateTime <= '2014-11-19 13:01:01'
ORDER BY CONCAT(T1.FieldA, ',', T1.FieldB);

Related

Hibernate query not returning Zero value

Same query working in SQL
Select count(tbl_leads.lead_Status_Id) , tbl_LeadStatus.LeadStatus_Type FROM tbl_LeadStatus LEFT JOIN tbl_leads ON tbl_LeadStatus.LeadStatus_id = tbl_leads.lead_Status_Id GROUP BY tbl_LeadStatus.LeadStatus_Type;
Hibernate Query
Select s.LeadStatus_Type, count(l.status) FROM Status s "
+ "LEFT JOIN Lead l ON l.status = s.LeadStatus_id "
+ "GROUP BY s.LeadStatus_Type"
Expecting output is this
Count LeadStatus_Type
'0' 'Cancelled'
'0' 'In-Progress'
'1' 'New'
'0' 'Sold'
'0' 'UnAssigned'
And HQL return this
'1', 'New'
Your join condition looks off. In HQL we join from an entity to the other entity which exists as a property of the first entity. Most importantly, there is no ON clause as that relationship is already known within Hibernate. Try the following:
SELECT s.LeadStatus_Type, COUNT(l.status)
FROM Status s
LEFT JOIN s.LeadStatus_id l
GROUP BY s.LeadStatus_Type

Hibernate Inner Join OneToMany Mapping throws HibernateQueryException

I am new to Hibernate. I have established a OneToMany mapping between User and Expense. I am trying to return expenses for a User for the last week.
This is the MySQL query that I am using.
select SUM(amount) from Expense INNER JOIN User ON Expense.user_id = User.id AND User.username ='testUser' WHERE created >= curdate() - INTERVAL DAYOFWEEK(curdate())+1 DAY AND created < curdate() - INTERVAL DAYOFWEEK(curdate())-1 DAY;
When I try to use this query in hibernate, I get a HibernateQueryException
String query = "select SUM(amount) from Expense INNER JOIN User ON Expense.user_id = User.id AND user.username ='sarvam' WHERE created >= curdate() - INTERVAL DAYOFWEEK(curdate())+1 DAY AND created < curdate() - INTERVAL DAYOFWEEK(curdate())-1 DAY";
List list = session.createQuery(query).list();
The error I get is-
Exception in thread "main" org.hibernate.QueryException: outer or full join must be followed by path expression [select SUM(amount) from com.challenge.pojo.Expense INNER JOIN User ON Expense.user_id = User.id AND user.username ='sarvam' WHERE created >= curdate() - INTERVAL DAYOFWEEK(curdate())+1 DAY AND created < curdate() - INTERVAL DAYOFWEEK(curdate())-1 DAY]
at org.hibernate.QueryException.generateQueryException(QueryException.java:120)
at org.hibernate.QueryException.wrapWithQueryString(QueryException.java:103)
at org.hibernate.hql.internal.classic.QueryTranslatorImpl.compile(QueryTranslatorImpl.java:233)
at org.hibernate.hql.internal.classic.QueryTranslatorImpl.compile(QueryTranslatorImpl.java:193)
at org.hibernate.engine.query.spi.HQLQueryPlan.<init>(HQLQueryPlan.java:115)
at org.hibernate.engine.query.spi.HQLQueryPlan.<init>(HQLQueryPlan.java:76)
at org.hibernate.engine.query.spi.QueryPlanCache.getHQLQueryPlan(QueryPlanCache.java:150)
at org.hibernate.internal.AbstractSessionImpl.getHQLQueryPlan(AbstractSessionImpl.java:298)
at org.hibernate.internal.AbstractSessionImpl.createQuery(AbstractSessionImpl.java:236)
at org.hibernate.internal.SessionImpl.createQuery(SessionImpl.java:1825)
at com.challenge.dao.ExpenseDAO.getExpensesForLastWeek(ExpenseDAO.java:52)
at com.challenge.dao.ExpenseDAO.getExpensesForLastWeek(ExpenseDAO.java:44)
at com.challenge.dao.Test.main(Test.java:27)
Caused by: org.hibernate.QueryException: outer or full join must be followed by path expression
at org.hibernate.hql.internal.classic.FromParser.token(FromParser.java:253)
at org.hibernate.hql.internal.classic.ClauseParser.token(ClauseParser.java:93)
at org.hibernate.hql.internal.classic.PreprocessingParser.token(PreprocessingParser.java:118)
at org.hibernate.hql.internal.classic.ParserHelper.parse(ParserHelper.java:43)
at org.hibernate.hql.internal.classic.QueryTranslatorImpl.compile(QueryTranslatorImpl.java:223)
... 10 more
Can anyone please help me fix it.
createQuery(String queryString) Create a new instance of Query for the
given HQL query string.
createSQLQuery(String queryString)
Create a new instance of SQLQuery for the given SQL query string.
You're using the first one which expects HQL as an input, for using native SQL you sould use the second one.
String query = "select SUM(amount) from Expense INNER JOIN User ON Expense.user_id = User.id AND user.username ='sarvam' WHERE created >= curdate() - INTERVAL DAYOFWEEK(curdate())+1 DAY AND created < curdate() - INTERVAL DAYOFWEEK(curdate())-1 DAY";
List list = session.createSQLQuery(query).list();
Session Documentation
You might want to take a look at: I can't make a inner join between two tables in hibernate hql query
If using HQL you have to their Object-Oriented style which might look something like this:
String query = "select SUM(amount) from Expense exp INNER JOIN User u ON e.user_id = u.id AND u.username = 'sarvam' ...";
List list = session.createQuery(query).list();
(untested)
Alternatively you can keep using standard SQL syntay if you instead use:
List list = session.createSQLQuery(query).list();
Then you might want to read Chapter 16 of the Hibernate Documentation.
Keep in mind that the SQL dialect depends on the underlying Database. Depending on your Application there might be a different database used on a different system which could break your SQL statements.

Need to know the right syntax of a count query to count rows by id

I got these two tables and I want to have a query to count the amount of cars by each brand and insert this count to a column in the brand table
I've tried many queries but can't get it right.
First table,
Second table,
Use JOIN.
Query
select t1.car_brand_id, t2.brand_name, count(t1.car_name) as total_count
from table1 t1
join table2 t2
on t1.car_brand_id = t2.brand_id
group by t1.car_brand_id, t2.brand_name;
You need join count and group by
this is a select for see the count by brand_name
select b.brand_name, count(*)
from table_one a
inner join table_two b on b.brand_id = a.brand_id
group by b.brand_name
Once you have added the column you need in table_two ( with eg alter table command adding my_count_col)
you could use an update like this
update table_two
inner join (
select b.brand_name, count(*) my_count
from table_one a
inner join table_two b on b.brand_id = a.brand_id
group by b.brand_name ) t on t.brand_name = table_two.brand_name
set table_two.my_count_col = t.my_count

Can you have multiple inner joins with a where clause that only effects one of the joins?

This is my sql command:
SELECT GIG.GIG_DESCRIPTION, VENUES.VENUE_NAME, BAND.BAND_NAME,
CASE WHEN GIG.USERID = 0 THEN '--CREATED BY THE BAND--' ELSE USERS.USERNAME END,
GIG.GIG_DATE
from GIG
INNER JOIN VENUES ON GIG.VENUEID = VENUES.VENUEID
INNER JOIN BAND ON GIG.BANDID = BAND.BANDID
INNER JOIN USERS ON GIG.USERID = USERS.USERID
WHERE GIG.USERID != 0
AND GIG.GIGID=" + gigID;
I'm using this query to return some values for a java object. In the Gig table sometimes the userid will equal 0, I'm getting a null pointer exception when I try and return a row with the userid equal to 0. I think I can get rid of the error if that last inner join on the users isn't run if a certain condition isn't true. Can I use a where clause that only effects the last join? How would I do that?
I think that you need link the USERS table using a LEFT JOIN clause in order to not discard the results with userid = 0 and remove the GIG.USERID != 0 on the WHERE clause:
SELECT GIG.GIG_DESCRIPTION, VENUES.VENUE_NAME, BAND.BAND_NAME,
CASE WHEN GIG.USERID = 0 THEN '--CREATED BY THE BAND--' ELSE
USERS.USERNAME END,
GIG.GIG_DATE
from GIG
INNER JOIN VENUES ON GIG.VENUEID = VENUES.VENUEID
INNER JOIN BAND ON GIG.BANDID = BAND.BANDID
LEFT JOIN USERS ON GIG.USERID = USERS.USERID
WHERE GIG.GIGID=" + gigID;
You can have multiple conditions in a join, try something like
INNER JOIN USERS ON GIG.USERID = USERS.USERID AND GIG.USERID != 0
WHERE ...
The where clause is applied to the result of the joins, so it can't be limited to just the last inner join.
You can add your condition to the where clause, of course. But you should keep in mind that it will affect the whole join.
I would suggest you add your condition to your on clause for the particular join.

SQL statement (Oracle) that selects rows from tbl NOT IN pattern (selected from joined tables)

I have two tables: tblAPARTMENT and tblRESERVATION. I want a list of all apartmentID's which are not in the reservation-table with those dates.
I have tried:
SELECT apartmentID, apartmentNAME
FROM tblAPARTMENT
NOT IN
(SELECT apartmentID FROM tblRESERVATION
WHERE tblRESERVATION.startDate > _a-date_
AND tblRESERVATION.endDate < _a-date_
I know there is a better way to write this, I just cant figure it out.
The syntactically correct way to write your query is:
SELECT a.apartmentID, a.apartmentNAME
FROM tblAPARTMENT a
WHERE a.apartmentID NOT IN (SELECT a.apartmentID
FROM tblRESERVATION r
WHERE r.startDate <= _a-date_ AND r.endDate >= _a-date_
);
This is a reasonable way, but it is generally safer to use not exists rather than not in (due to NULL handling):
SELECT a.apartmentID, a.apartmentNAME
FROM tblAPARTMENT a
WHERE NOT EXISTS (SELECT a.apartmentID
FROM tblRESERVATION r
WHERE r.startDate <= _a-date_ AND r.endDate >= _a-date_ and
r.apartmentid = a.apartmentid
);
how about this..? it will query apartmentIDs which are outside your specified date (in your original post) boundary..
SELECT tr.apartmentID, ta.apartmentNAME
FROM tblRESERVATION tr JOIN tblAPARTMENT ta
ON tr.apartmentID =ta.apartmentID
AND tr.startDate <= _a-date_
AND tr.endDate >= _a-date_
UPDATE:
actually I don't really know what you want..
if above query doesn't give you the result you want, you might wanna change this:
AND tr.startDate <= _a-date_
AND tr.endDate >= _a-date_
to:
AND (tr.startDate <= _a-date_
OR tr.endDate >= _a-date_)

Categories

Resources