i can't make hibernate sql query - sql

hi i am a noob programmer.
I am learning Hibernate now. And I am frustrated by
SELECT COUNT(*) FROM zipcode a
WHERE (ISNULL( :sido , '') = '' OR a.sido = :sido) AND
(ISNULL( :sigungu , '') = '' OR a.sigungu = :sigungu) AND
(ISNULL( :eupmyun , '') = '' OR a.eupmyun = :eupmyun) AND
(ISNULL( :roadName , '') = '' OR a.road_name = :roadName) AND
(ISNULL( :ri , '') = '' OR a.ri = :ri)
I can't make this sql query to hibernate....
Number num = (Number) session()
.createQuery(
"SELECT COUNT(*) FROM ZipCode a WHERE (ISNULL( :sido , '') = '' OR a.sido = :sido) AND (ISNULL( :sigungu , '') = '' OR a.sigungu = :sigungu) AND (ISNULL( :eupmyun , '') = '' OR a.eupmyun = :eupmyun) AND(ISNULL( :roadName , '') = '' OR a.roadName = :roadName) AND(ISNULL( :ri , '') = '' OR a.ri = :ri) ")
.setParameter("sido", sido).setParameter("sigungu", sigungu).setParameter("eupmyun", eupmyun).setParameter("roadName", roadName).setParameter("ri", ri)
.list();
I try this sql...
I am using Postgresql 9.4 and hibernate 5.0.*
Please help me

1) Instead of createQuery use createSQLQuery as below:
Query query = session.createSQLQuery("SELECT COUNT(*) FROM zipcode a
WHERE (ISNULL( :sido , '') = '' OR a.sido = :sido) AND
(ISNULL( :sigungu , '') = '' OR a.sigungu = :sigungu) AND
(ISNULL( :eupmyun , '') = '' OR a.eupmyun = :eupmyun) AND
(ISNULL( :roadName , '') = '' OR a.road_name = :roadName) AND
(ISNULL( :ri , '') = '' OR a.ri = :ri) ");
Number number =(Number)query.list().get(0);
createQuery - is a HQL query whereas createSQLQuery is a native db query.
Note: make sure the query is in one line else you need to add ('+') concat operator.

Related

How to speed up a SQL query which is using DISTINCT

From what I have read about this it seems like the best solution is to create an INDEX but I am not sure which columns I should be creating indexes for. This is my first time working with SQL indexes.
If I remove the DISTINCT call from this query I get over 1000 results in just over a second. However with the DISTINCT call it returns the results in 10 seconds (obviously without the duplicates).
If anyone has any alternative solutions I am all ears.
This is the query (the second SELECT is where the DISTINCT function is called):
SELECT
Sku,
Name,
ccp.Polygon,
MarketAvailability,
Coverage,
Range
FROM
(SELECT DISTINCT
dbo.CatalogEntry.CatalogEntryId as Id,
dbo.CatalogEntry.Code as Sku,
CoverageNode.Name as Coverage,
RangeNode.Name as [Range],
(SELECT CatalogContentProperty.LongString
FROM CatalogContentProperty
WHERE MetaFieldName = 'ItemChartName'
AND (CatalogContentProperty.LongString IS NOT NULL)
AND (CatalogContentProperty.ObjectId = dbo.CatalogEntry.CatalogEntryId)) AS [Name],
(SELECT CatalogContentProperty.LongString
FROM CatalogContentProperty
WHERE MetaFieldName = 'MarketAvailabilityDetailsCollection'
AND (CatalogContentProperty.LongString IS NOT NULL)
AND (CatalogContentProperty.ObjectId = dbo.CatalogEntry.CatalogEntryId)) AS MarketAvailability
FROM
dbo.CatalogEntry
INNER JOIN
dbo.NodeEntryRelation ON dbo.CatalogEntry.CatalogEntryId = dbo.NodeEntryRelation.CatalogEntryId
INNER JOIN
dbo.CatalogNode AS CoverageNode ON dbo.NodeEntryRelation.CatalogNodeId = CoverageNode.CatalogNodeId
INNER JOIN
dbo.CatalogNode AS RangeNode ON CoverageNode.ParentNodeId = RangeNode.CatalogNodeId
INNER JOIN
dbo.CatalogContentProperty ON dbo.CatalogEntry.CatalogEntryId = dbo.CatalogContentProperty.ObjectId
INNER JOIN
dbo.CatalogNode AS ModelNode ON RangeNode.ParentNodeId = ModelNode.CatalogNodeId
INNER JOIN
dbo.CatalogNode AS BrandNode ON ModelNode.ParentNodeId = BrandNode.CatalogNodeId
WHERE
(dbo.CatalogEntry.ClassTypeId = N'Variation') AND
(dbo.CatalogContentProperty.MetaFieldName = N'ItemIsChart') AND
RangeNode.Name != 'C-MAP' AND
(BrandNode.Name = '' OR '' = '' OR '' IS NULL) AND
(ModelNode.Name = '' OR '' = '' OR '' IS NULL) AND
(CoverageNode.Name = '' OR '' = '' OR '' IS NULL) AND
(RangeNode.Name = '' OR '' = '' OR '' IS NULL)
) AS CmapResults
INNER JOIN
(SELECT
GEOMETRY::STGeomFromText(CatalogContentProperty.LongString,4326) AS PolygonGeometry,
CatalogContentProperty.LongString AS Polygon,
CatalogContentProperty.ObjectId
FROM
CatalogContentProperty
WHERE
MetaFieldName = 'ItemChartCoordinates' AND
(CatalogContentProperty.LongString IS NOT NULL)) ccp ON ccp.ObjectId = CmapResults.Id
WHERE
((GEOGRAPHY::STGeomFromText(PolygonGeometry.MakeValid().STUnion(PolygonGeometry.MakeValid().STStartPoint()).STAsText(), 4326).STDistance(GEOGRAPHY::STGeomFromText('POINT(50.9835929 -1.4205852)', 4326)) / 1609.344) <= 100 OR 'POINT(50.9835929 -1.4205852)' IS NULL)
AND MarketAvailability IS NOT NULL
ORDER BY
GEOGRAPHY::STGeomFromText(PolygonGeometry.MakeValid().STUnion(PolygonGeometry.MakeValid().STStartPoint()).STAsText(), 4326).STArea() DESC;
I am using SQL Server Management Studio 2012. The aim is to get the query with the DISTINCT call to return in the same amount of time as the query would without the DISTINCT call.
Your query looks a bit complicated. Will this one produce the same output?
SELECT DISTINCT ce.Code as Sku
, max(case when ccp.MetaFieldName = 'ItemChartName' then ccp.LongString end) as 'Name'
, max(case when ccp.MetaFieldName = 'MarketAvailabilityDetailsCollection' then ccp.LongString end) as 'MarketAvailability'
, max(case when ccp.MetaFieldName = 'ItemChartCoordinates' then ccp.LongString end) as 'Polygon'
, CoverageNode.Name as Coverage
, RangeNode.Name as 'Range'
FROM dbo.CatalogEntry ce
INNER JOIN dbo.NodeEntryRelation ner ON ce.CatalogEntryId = ner.CatalogEntryId
INNER JOIN dbo.CatalogNode CoverageNode ON dbo.NodeEntryRelation.CatalogNodeId = CoverageNode.CatalogNodeId
INNER JOIN dbo.CatalogNode RangeNode ON CoverageNode.ParentNodeId = RangeNode.CatalogNodeId
INNER JOIN dbo.CatalogContentProperty ccp ON ce.CatalogEntryId = ccp.ObjectId
INNER JOIN dbo.CatalogNode ModelNode ON RangeNode.ParentNodeId = ModelNode.CatalogNodeId
INNER JOIN dbo.CatalogNode BrandNode ON ModelNode.ParentNodeId = BrandNode.CatalogNodeId
WHERE ce.ClassTypeId = N'Variation'
and ccp.MetaFieldName = N'ItemIsChart'
and RangeNode.Name != 'C-MAP'
--and (BrandNode.Name = '' OR '' = '' OR '' IS NULL) -- always true
--and (ModelNode.Name = '' OR '' = '' OR '' IS NULL) -- always true
--and (CoverageNode.Name = '' OR '' = '' OR '' IS NULL) -- always true
--and (RangeNode.Name = '' OR '' = '' OR '' IS NULL) -- always true
and (GEOGRAPHY::STGeomFromText(GEOMETRY::STGeomFromText(ccp.LongString,4326).MakeValid().STUnion(GEOMETRY::STGeomFromText(ccp.LongString,4326).MakeValid().STStartPoint()).STAsText(), 4326).STDistance(GEOGRAPHY::STGeomFromText('POINT(50.9835929 -1.4205852)', 4326)) / 1609.344) <= 100 -- OR 'POINT(50.9835929 -1.4205852)' IS NULL -- redundant
)
and max(case when ccp.MetaFieldName = 'MarketAvailabilityDetailsCollection' then ccp.LongString end)
ORDER BY GEOGRAPHY::STGeomFromText(GEOMETRY::STGeomFromText(ccp.LongString,4326).MakeValid().STUnion(GEOMETRY::STGeomFromText(ccp.LongString,4326).MakeValid().STStartPoint()).STAsText(), 4326).STArea() DESC;
So the answer is my case was to remove the DISTINCT and to do the duplicate removing using LINQ! Load times went from 10-11ish seconds to 4-5ish seconds

conditional clause in Claudera

I am trying to get an if, then clause working in cloudera - along the lines:
if (appointment_purpose = '') and
appointment_purpose2 = '') and
appointment_type2 = '') and
appointment_type3 = '') and
appointment_type4 = '') and
appointment_type5 = '') and
discuss_other ' ') then
discuss_other = 0
else discuss_other = 1,
How do I get this to work?
If all appointment types and appointment purposes were empty, then discuss_other should also be empty, that is 0 - otherwise discuss_other should be 1
Try this:
SELECT (CASE WHEN appointment_purpose = ''
AND appointment_purpose2 = ''
AND appointment_type2 = ''
AND appointment_type3 = ''
AND appointment_type4 = ''
AND appointment_type5 = ''
AND discuss_other ' '
THEN 0
ELSE 1
) as discuss_other
FROM tableName
In SQL, "empty" typically means NULL. So, I wonder if you really intend one of these constructs:
select (case when appointment_purpose is null and
appointment_purpose2 is null and
appointment_type2 is null and
appointment_type3 is null and
appointment_type4 is null and
appointment_type5 is null and
discuss_other is null
then 0 else 1
end) as discuss_other
Because one of the values has a space, I wonder if you want to handle both spaces and null values:
select (case when (appointment_purpose is null or replace(appointment_purpose, ' ', '') = '') and
(appointment_purpose2 is null or replace(appointment_purpose2, ' ', '') = '') and
(appointment_purpose3 is null or replace(appointment_purpose3, ' ', '') = '') and
(appointment_purpose4 is null or replace(appointment_purpose4, ' ', '') = '') and
(appointment_purpose5 is null or replace(appointment_purpose5, ' ', '') = '') and
(discuss_other is null or replace(discuss_other, ' ', '') = '')
then 0 else 1
end) as discuss_other
Finally, multiple columns in the same table that are acting like an array is usually a bad sign. Normally, this suggests that you want a junction table.

Execute the SQL query with if statement in Where clause

Need to execute the SQL query with IF statement in Where clause.
SELECT
CASE
WHEN Isnull(CustGuarFlag ,'') = '' THEN DocName
ELSE DocName + ' - '+
CASE
WHEN CustGuarFlag= 'C' THEN 'Customer'
ELSE 'Guarantor'
END
END DocName,
ISNULL(A.DOCSTAGE, '') DOCSTAGE,
ISNULL(A.DOCREFNO,'') DOCREFNO,
ISNULL(CONVERT(VARCHAR, A.DOCREFDT, 103), '') DOCREFDT,
ISNULL(CONVERT(VARCHAR, A.RECDDT, 103), '') RECDDT ,
ISNULL(A.DOCVALUE, 0) DOCVALUE ,
ISNULL(CONVERT(VARCHAR, A.DOCVLDUPTO, 103), '') DOCVLDUPTO,
a.pk_id AS AppDocpk,
b.pk_id AS Docpk,
CASE
WHEN Isnull(a.DocVerifiedStatus, '') = 'null'
THEN ''
ELSE Isnull(a.DocVerifiedStatus,'')
END AS DocVerifiedStatus,
ISNULL(RejRemarks, '') AS RejRemarks,
ISNULL(KYCDocHdr_Fk, 0) AS KYCPk,
ISNULL(DocShrtDescr, '') AS DocShrtDescr
FROM
loln_apprvldoc A WITH(NOLOCK)
JOIN
LGEN_DOCUMENTS B WITH(NOLOCK) ON A.Doc_FK = B.PK_ID
LEFT OUTER JOIN
Lgen_KYCApprvlDoc c ON a.KYCDocHdr_Fk = c.PK_Id
WHERE
A.PRPSLNO = 'KATHU1602080002'
AND ISNULL(A.DocStat, '') = 'R'
AND ISNULL(A.DocVerifiedStatus, '') IN ('Rejection', '', 'null')
AND CASE
WHEN Isnull(c.DocVerifiedStatus, '') = 'A'
THEN c.Pk_id IS NOT NULL
ELSE c.Pk_id IS NULL
END
CASE doesn't belong in a WHERE clause. Replace that CASE clause with
(
(Isnull(c.DocVerifiedStatus,'')='A' AND c.Pk_id IS NOT NULL)
OR
(Isnull(c.DocVerifiedStatus,'')<>'A' AND c.Pk_id IS NULL)
)

Why query takes more time to execute when I use if else statement in stored procedure?

I have used below query in my stored procedure. When I am using if else statement in the stored procedure query takes more time to execute. When I remove if else statement query takes less time to return result.
If #P_Make = 'ALL' Or IsNull(#P_Make, '') = ''
Begin
Set #P_Make = '%';
End
Else
Begin
Set #P_Make = #P_Make + '%';
End
If #P_Model = 'ALL' Or IsNull(#P_Model, '') = ''
Begin
Set #P_Model = '%';
End
Else
Begin
Set #P_Model = #P_Model + '%';
End
If #P_Location = 'ALL' Or IsNull(#P_Location, '') = ''
Begin
Set #P_Location = '%';
End
Else
Begin
Set #P_Location = #P_Location + '%';
End
If #P_City = 'ALL' Or IsNull(#P_City, '') = ''
Begin
Set #P_City = '%';
End
Else
Begin
Set #P_City = #P_City + '%';
End
If #P_Category = 'ALL' Or IsNull(#P_Category, '') = ''
Begin
Set #P_Category = '%';
End
Else
Begin
Set #P_Category = Case When #P_Category = 'Bikes & Scooters' Then '2W%'
When #P_Category = '3 Wheelers' Then '3W%'
When #P_Category = 'Cars & SUVs' Then '4W%'
When #P_Category = 'Trucks' Then 'CV%'
When #P_Category = 'Farm Equipments' Then 'FE%'
When #P_Category = 'Industrial Equipments' Then 'IE%'
When #P_Category = 'Construction Equipments' Then 'CE%'
Else #P_Category + '%'
End
End
If #P_Service = 'ALL' Or IsNull(#P_Service, '') = ''
Begin
Set #P_Service = ''
End
Select Count(C.Sal_Pk_Id)
From dbo.Auction (NoLock) A
Inner Join dbo.PLACE (NoLock) B On A.Auc_Place_Fk_Id = B.Place_Pk_Id
Inner Join dbo.SALES_DETAILS (NoLock) C On A.Auc_Code = C.Sal_Auc_Code
Inner Join dbo.AUCTIONSERVICES (NoLock) D On C.Sal_Regno = D.Auc_Service_Regno And C.Sal_Auc_Code = D.Auc_Service_Auctioncode
Inner Join dbo.LOT (NoLock) E On C.Sal_Lot_No = E.Lot_Lot_No And C.Sal_Auc_Code = E.Lot_Auc_Code
Inner Join dbo.INVENTORY (NoLock) F On C.Sal_Regno = F.Inv_H_Reg_No
Where C.[Status] = 'L' And E.Lot_Sold_Status = 'S'
And IsNull(B.Place_City, '') Like #P_City And IsNull(B.Place_State, '') Like #P_Location
And IsNull(F.Inv_H_Category, '') Like #P_Category And IsNull(F.Inv_H_Mfg_Name, '') Like #P_Make
And IsNull(F.Inv_H_Model, '') Like #P_Model
Query without if else statement:
Select Count(C.Sal_Pk_Id)
From dbo.Auction (NoLock) A
Inner Join dbo.PLACE (NoLock) B On A.Auc_Place_Fk_Id = B.Place_Pk_Id
Inner Join dbo.SALES_DETAILS (NoLock) C On A.Auc_Code = C.Sal_Auc_Code
Inner Join dbo.AUCTIONSERVICES (NoLock) D On C.Sal_Regno = D.Auc_Service_Regno And C.Sal_Auc_Code = D.Auc_Service_Auctioncode
Inner Join dbo.LOT (NoLock) E On C.Sal_Lot_No = E.Lot_Lot_No And C.Sal_Auc_Code = E.Lot_Auc_Code
Inner Join dbo.INVENTORY (NoLock) F On C.Sal_Regno = F.Inv_H_Reg_No
Where C.[Status] = 'L' And E.Lot_Sold_Status = 'S'
And (#P_City = '' Or IsNull(B.Place_City, '') = #P_City)
And (#P_Location= '' Or IsNull(B.Place_State, '') = #P_Location)
And (#P_Category = '' Or IsNull(F.Inv_H_Category, '') = #P_Category)
And (#P_Make = '' Or IsNull(F.Inv_H_Mfg_Name, '') = #P_Make)
And (#P_Model = '' Or IsNull(F.Inv_H_Model, '') = #P_Model)
Why the query output takes less time when I remove if else statement in the stored procedure?
There's two main reasons - like and execution plan.
like '%something' is the slowest possible thing you can filter by - it means going row by row, reading the whole data in the column and doing a comparison. It can't use any index seeks, only scans.
Second, you only get one execution plan, based on the first way the procedure is called. This pretty much guarantees that for any other input data, the performance will suffer. In your second example, while the plan is again sub-optimal and dependent on the initial inputs, it doesn't completely ignore all the possible filters - it just optimizes based on statistics.
Dynamic filters aren't something nobody tried to solve before. Learn from the best: http://www.sommarskog.se/dyn-search.html
I think the query without if else is faster because it does not have a Like operator
Where C.[Status] = 'L' And E.Lot_Sold_Status = 'S'
And IsNull(B.Place_City, '') Like #P_City And IsNull(B.Place_State, '') Like #P_Location
And IsNull(F.Inv_H_Category, '') Like #P_Category And IsNull(F.Inv_H_Mfg_Name, '') Like #P_Make
And IsNull(F.Inv_H_Model, '') Like #P_Model
and I suppose that the second query can use indexes more efficiently. The first and second queries are different, please look at Actual Execution Plan and you will realize why it happens.

where condition depending on parameter

I'm a sql newbie, I use mssql2005
I like to do select with the condition which is depending on the input parameter
I've tried this.
WHERE CF.PROCESS_DATE = '2010-05-05' AND
CASE #CATEGORY_LEVEL
WHEN 'L' THEN CAS.MCATEGORY_ID = '' AND CAS.SCATEGORY_ID = ''
WHEN 'M' THEN CAS.SCATEGORY_ID = ''
END
but didn't work and happened an error.
sql is difficult to newbie programmer.. T.T
You could rewrite the condition as:
WHERE CF.PROCESS_DATE = '2010-05-05' AND
(
(#CATEGORY_LEVEL = 'L' AND CAS.MCATEGORY_ID = '' AND CAS.SCATEGORY_ID = '') OR
(#CATEGORY_LEVEL = 'M' AND CAS.SCATEGORY_ID = '')
)
WHERE CF.PROCESS_DATE = '2010-05-05' AND
(
(#CATEGORY_LEVEL = 'L' AND CAS.MCATEGORY_ID = '' AND CAS.SCATEGORY_ID = '')
OR
(#CATEGORY_LEVEL = 'M' AND CAS.SCATEGORY_ID = '')
)
(Un)fortunately, your code works on other database(e.g. Postgres, MySQL), SQL Server don't have first class support for boolean, so your expression after of THEN won't result to boolean type, hence will not work in Sql Server