How to make count(*) query work in Hibernate from unmapped entities? - sql

I am new to Hibernate. And here I successfully used SQL query as is using session.createSQLQuery():
SELECT t2.col1, t2.col2, t2.col3, t5.col4, t1.col5, t4.col6, t4.col7,
DECODE(t1.col8,null,t1.col9,t1.col8), t1.col10, t1.col11, t8.col12
FROM table1 t1
JOIN table2 t2
ON t1.xyz = t2.xyz
JOIN table3 t3
ON t2.col3 = t3.col3
LEFT JOIN view1 t4
ON t1.abc = t4.abc1
LEFT JOIN view2 t5
ON t1.abc10 = t5.abc2 AND t5.xyz1 = 1
JOIN table6 t6
ON t2.abc8 = t6.abc9
JOIN table7 t7
ON t6.xyz2 = t7.xyz2
LEFT JOIN table8 t8
ON t2.col1 = t8.abc3 AND t8.abc5 = 'XYZ' AND t8.abc6 = 1234
WHERE t2.DISPLAY = 'true'
AND t2.abc4 = 0
AND t6.abc7 = 0
AND t2.col2 = 0
So I don't have all those entities Java objects. And no mapping xml file. But this query does not work when I use "SELECT COUNT(*) FROM " It is giving me an error "unexpected token ON". So how to fix select COUNT(*)? Thank you.

You need a group by to do COUNT(*).
group by the values you select and you should have your count ;)

Related

Multiple IN subqueries in WHERE

I am facing issues when trying to translate the following query from impala to hive 1.1 on cloudera 5.8.
SELECT *
FROM
table1 t1,table2 t2
WHERE concat(t1.field1, t1.field2) IN
(SELECT concat(T3.field1, T3.field2)
FROM table3 T3
WHERE T3.field3 = 'value')
AND concat(t1.field3, t1.field4) IN
(SELECT concat(T3.field1, T3.field2)
FROM table3 T3
WHERE T3.field3 = 'value')
AND t1.some_field = t2.some_field
The error I get here states that I can't do multiple subqueries in the where clause.
Only 1 SubQuery expression is supported.
I have tried working around this issue by using union, but in this version only union all is supported. I am not really sure on how I could use a join here to fix this as well.
I would appreciate suggestions on how to rewrite this query so it produces the expected result without throwing errors.
Using Joins and CTE:
with s3 as (SELECT T3.field1, T3.field2
FROM table3 T3
WHERE T3.field3 = 'value')
SELECT *
FROM
table1 t1
inner join table2 t2 on t1.some_field = t2.some_field
left semi join s3 on t1.field1=s3.field1
and t1.field2=s3.field2
left semi join s3 on t1.field3=s3.field1
and t1.field4=s3.field2
Their documentation says that you can use CTE.
https://cwiki.apache.org/confluence/display/Hive/Common+Table+Expression
Can you try this?
WITH firstConcatResult AS (
SELECT * FROM
table1 t1,table2 t2
WHERE
//first concat
)
SELECT * FROM firstConcatResult f
WHERE
//other concat
I would use exists and proper join syntax:
SELECT *
FROM table1 t1 JOIN
table2 t2
ON t1.some_field = t2.some_field
WHERE EXISTS (SELECT 1
FROM table3 T3
WHERE T3.field3 = 'value' AND
T3.field1 = t1.field1 AND t3.field2 = t1.field2
) AND
EXISTS (SELECT 1
FROM table3 T3
WHERE T3.field3 = 'value' AND
T3.field1 = t1.field3 AND t3.field2 = t1.field4
);

Subquery in Inner join - Multi-part identifer could not be bound

I have the following query and I am getting a multi-part identifier could not be bound exception. I realize why and my next thought was to use a CROSS APPLY, which didn't work. What I really need to do is join that subquery to make sure I get the most recent entry for a particular column.
Unfortunately, I've run out of ideas... How do I accomplish this query?
SELECT t1.*
FROM dbo.Table1 t1 (nolock)
INNER JOIN
(
SELECT TOP 1 t2_s.c1, t2_s.c2, t2_s.c4
FROM dbo.Table2 t2_s
WHERE t2_s.c1 = t1.c1
ORDER BY t2_s.dateStamped DESC
) t2
on t2.c1 = t1.c1
INNER JOIN dbo.Table3 t3
on t3.c1 = t2.c2 and t3.c2 = 1
WHERE t1.c2 = 'xxx'
Assuming you are using SQL Server, then CROSS APPLY should do what you want:
SELECT t1.*
FROM dbo.Table1 t1 (nolock) CROSS APPLY
(SELECT TOP 1 t2_s.c1, t2_s.c2, t2_s.c4
FROM dbo.Table2 t2_s
WHERE t2_s.c1 = t1.c1
ORDER BY t2_s.dateStamped DESC
) t2 INNER JOIN
dbo.Table3 t3
on t3.c1 = t2.c2 and t3.c2 = 1
WHERE t1.c2 = 'xxx';

Merging different conditional select queries into one - with structure

I have a query in SQL Server 2008 as below:
;with PassiveCases
AS
(
Select t1.id, COUNT(*) as PassiveCounts
from #Table1 t1
inner join Table2 t2 on t2.Id = t1.SurgicalRequest_Id
inner join Table3 t3 on t3.Id = t2.ReportingIndicator_Id
inner join Table3 t4 on t4.Id = t3.Id
where t4.Passive = 1
),
ActiveCases
AS
(
Select t1.id, COUNT(*) as ActiveCounts
from #Table1 t1
inner join Table2 t2 on t2.Id = t1.SurgicalRequest_Id
inner join Table3 t3 on t3.Id = t2.ReportingIndicator_Id
inner join Table3 t4 on t4.Id = t3.Id
where t4.Passive = 0
)
What I want it to combine these structures into one to increase the efficiency and provide more readability. I am looking for something like below (it doesn't work)
:With Cases
AS
(
Select t1.id, case when t4.Passive = 1 then COUNT(*) as PassiveCounts else COUNT(*) as ActiveCounts
from #Table1 t1
inner join Table2 t2 on t2.Id = t1.SurgicalRequest_Id
inner join Table3 t3 on t3.Id = t2.ReportingIndicator_Id
inner join Table3 t4 on t4.Id = t3.Id
)
Any help would be appreciated.
Use conditional aggregation.
Select t1.id
,sum(case when t4.Passive = 1 then 1 else 0 end) as PassiveCounts
,sum(case when t4.Passive <> 1 then 1 else 0 end) as ActiveCounts
from #Table1 t1
inner join Table2 t2 on t2.Id = t1.SurgicalRequest_Id
inner join Table3 t3 on t3.Id = t2.ReportingIndicator_Id
inner join Table3 t4 on t4.Id = t3.Id
group by t1.id
You just want conditional aggregation. In your case, though, you can do this with arithmetic:
With Cases AS (
Select t1.id, sum(t4.Passive) as PassiveCount, sum(1 - t4.Passive) as ActiveCount
from #Table1 t1 inner join
Table2 t2
on t2.Id = t1.SurgicalRequest_Id inner join
Table3 t3
on t3.Id = t2.ReportingIndicator_Id inner join
Table3 t4
on t4.Id = t3.Id
group by t1.id
)
According to your question, t4.Passive only takes on two values, so the arithmetic should do what you want.

Oracle SQL: JOIN by dblink

I use next SQL-query in Oracle DB:
SELECT T1.*,
T3.*
FROM MyTable1 T1
INNER JOIN MyTable2 T2 ON T2.Id1 = T1.Id
LEFT JOIN MyTable3#dblink1 T3 ON T3.Id2 = T2.Id
This query is very simple and fast (about 1 min, T1 contain about 1 million rows, T3 more then 10 million rows). Now I want to use MyTable4 from dblink1 for filtering selected rows data. For it, I use subquery:
SELECT T1.*,
T3.*
FROM MyTable1 T1
INNER JOIN MyTable2 T2 ON T2.Id1 = T1.Id
LEFT JOIN (SELECT Sub_T1.*
FROM MyTable3#dblink1 Sub_T1
INNER JOIN MyTable4#dblink1 Sub_T2 ON Sub_T2.Id3 = Sub_T1.Id
WHERE
Sub_T2.MyColumn1 = 'required value') T3 ON T3.Id2 = T2.Id
But this query is too slow (more then 20min). If I rewrite this query to:
SELECT T1.*,
T3.*
FROM MyTable1 T1
INNER JOIN MyTable2 T2 ON T2.Id1 = T1.Id
LEFT JOIN MyTable3#dblink1 T3 ON T3.Id2 = T2.Id
LEFT JOIN MyTable4#dblink1 T4 ON T4.Id3 = T3.Id
WHERE
T4.MyColumn1 = 'required value'
Then my query work fast again, but I donn't like result (I want to see columns of T3 as null, if WHERE return false).
How to improve my second query, for speed up it?
Does phrasing the query with parentheses solve the problem?
SELECT T1.*,
T3.*
FROM MyTable1 T1 INNER JOIN
MyTable2 T2
ON T2.Id1 = T1.Id LEFT JOIN
(MyTable3#dblink1 T3 JOIN
MyTable4#dblink1 T4
ON T4.Id3 = T3.Id AND
T4.MyColumn1 = 'required value'
)
ON T3.Id2 = T2.Id;
Or, also:
SELECT T1.*,
T3.*
FROM MyTable1 T1 INNER JOIN
MyTable2 T2
ON T2.Id1 = T1.Id LEFT JOIN
MyTable3#dblink1 T3
ON T3.Id2 = T2.Id
EXISTS (SELECT 1 FROM MyTable4#dblink1 T4 WHERE T4.Id3 = T3.Id AND T4.MyColumn1 = 'required value'
)

How to update a virtual Table with SQL?

I have this sql statement:
SELECT
t0.col0,
t0.col1,
t2.col0,
t2.col1,
t1.col0,
t1.col1,
t3.col3,
t3.col5,
t1.col2
FROM table0 t0
INNER JOIN table1 t1 ON t0.col0 = t1.col1
INNER JOIN table2 t2 ON t2.col0 = t1.col0
INNER JOIN table3 t3 ON t1.col0 = t3.col1
WHERE t1.col1 in (300, 301, 302, 302)
AND t2.col5 like 'V-%'
AND t3.delete = 'false'
this is working perfectly and shows a virtual table with the joined columns. So i try to directly update this Table like this way:
UPDATE T SET T.col1 = 1, T.col2 = '01.01.2012'
FROM (
SELECT
t0.col0,
t0.col1,
t2.col0,
t2.col1,
t1.col0,
t1.col1,
t3.col3,
t3.col5,
t1.col2
FROM table0 t0
INNER JOIN table1 t1 ON t0.col0 = t1.col1
INNER JOIN table2 t2 ON t2.col0 = t1.col0
INNER JOIN table3 t3 ON t1.col0 = t3.col1
WHERE t1.col1 in (300, 301, 302, 302)
AND t2.col5 like 'V-%'
AND t3.delete = 'false'
) as T
without success... The only way to made it was to create a View and proceed update on it.
But can i update in one statement a virtual Table?
You are not trying to update a table, but the output of a select statement. It's not a virtual table, because the output goes nowhere.
I think you need something like this.
UPDATE T SET t0.col0 = 1, t0.col1 = '01.01.2012'
FROM table0 t0
INNER JOIN table1 t1 ON t0.col0 = t1.col1
INNER JOIN table2 t2 ON t2.col0 = t1.col0
INNER JOIN table3 t3 ON t1.col0 = t3.col1
WHERE t1.col1 in (300, 301, 302, 302)
AND t2.col5 like 'V-%'
AND t3.delete = 'false'