Optimizing query in MS Access - sql

I have created this query using MS Access:
SELECT
Abonentai.vardas AS name,
Abonentai.pavarde AS name1,
Abonentai.email AS email,
Abonentai.Telefonas AS phone1,
Abonentai.[Gimimo metai] AS birthdate,
"" AS phone2,
"" AS name2,
Last(Abonentai.Suma) AS paycost,
Abonentai.vardas & " " & Abonentai.pavarde AS fullname,
Last(AbonentaiD.Planas) AS Abonement_Code,
Last(AbonentaiD.Nuo) AS Abonement_StartDate,
Last(AbonentaiD.Iki) AS Abonement_ExpDate,
Last(AbonentaiD.Kartai) - (SELECT COUNT(StatistikaID) FROM Statistika WHERE Statistika.AbonentasID = Abonentai.AbonentasID AND Statistika.AtvykimoData > (SELECT Last(AbonentaiD.Nuo) FROM AbonentaiD WHERE AbonentaiD.AbonentasID = Statistika.AbonentasID)) AS MAXQUANTVISIT,
Abonentai.ANr AS CARDNO,
"22" AS CARDTYPE,
"" AS INFO
FROM Abonentai
LEFT JOIN AbonentaiD ON Abonentai.AbonentasID = AbonentaiD.AbonentasID
WHERE
(((AbonentaiD.Iki)>Date())) AND (((AbonentaiD.Kartai) Is Null)) OR (((AbonentaiD.Kartai) Is Not Null) AND ((Abonentai.GaliojimoData)>Date()))
GROUP BY
Abonentai.vardas,
Abonentai.pavarde,
Abonentai.email,
Abonentai.Telefonas,
Abonentai.[Gimimo metai],
Abonentai.vardas & " " & Abonentai.pavarde,
Abonentai.ANr,
Abonentai.AbonentasID,
Abonentai.RegistracijosData
HAVING
Last(AbonentaiD.Kartai) - (SELECT COUNT(StatistikaID) FROM Statistika WHERE Statistika.AbonentasID = Abonentai.AbonentasID AND Statistika.AtvykimoData > (SELECT Last(AbonentaiD.Nuo) FROM AbonentaiD WHERE AbonentaiD.AbonentasID = Statistika.AbonentasID)) > 0
OR
Last(AbonentaiD.Kartai) - (SELECT COUNT(StatistikaID) FROM Statistika WHERE Statistika.AbonentasID = Abonentai.AbonentasID AND Statistika.AtvykimoData > (SELECT Last(AbonentaiD.Nuo) FROM AbonentaiD WHERE AbonentaiD.AbonentasID = Statistika.AbonentasID)) IS NULL
;
But it takes alot of time to excecute it. Is there any way to reduse excecution time? I need every vaue that I am selecting.

Related

Postgres Left Join ignores row if ManyToOne property is null

In Spring Boot i have the following query in a PostgreSQL database, to get data from ConfigElement table and set them to the new one ConfigurationReview table. It works properly as expected:
#Query(
"SELECT new xx.xx.xx.dao.ConfigurationReview(r.id, MAX(ce.id) AS configElementId,"
+ " r.checkMethod, r.targetDate, r.endDate, r.sessionDate, SUM(CASE WHEN i.criticality ="
+ " 0 AND i.relation = 0 THEN 1 ELSE 0 END) AS majorFindings, SUM(CASE WHEN i.criticality"
+ " = 1 AND i.relation = 0 THEN 1 ELSE 0 END) AS minorFindings, r.state) FROM"
+ " ConfigElement ce "
+ "LEFT JOIN ce.reviews r ON r.configElement.id = ce.id "
+ "LEFT JOIN r.criteria cr ON cr.review.id = r.id "
+ "LEFT JOIN cr.issues i ON i.criterion.id = cr.id "
+ "WHERE ce.id = :configurationId AND r.id IS NOT NULL GROUP BY r.id")
Page<ConfigurationReview> findConfigurationReviews(
#Param("configurationId") Long configurationId, Pageable pageable);
There was a need to add another property (r.milestone) with a ManyToOne relation, so i added it to the query:
#Query(
"SELECT new xx.xx.xx.dao.ConfigurationReview(r.id, MAX(ce.id) AS configElementId,"
+ " r.checkMethod, r.targetDate, r.endDate, r.sessionDate, SUM(CASE WHEN i.criticality ="
+ " 0 AND i.relation = 0 THEN 1 ELSE 0 END) AS majorFindings, SUM(CASE WHEN i.criticality"
+ " = 1 AND i.relation = 0 THEN 1 ELSE 0 END) AS minorFindings, r.state, r.milestone) FROM"
+ " ConfigElement ce "
+ "LEFT JOIN ce.reviews r ON r.configElement.id = ce.id "
+ "LEFT JOIN r.criteria cr ON cr.review.id = r.id "
+ "LEFT JOIN cr.issues i ON i.criterion.id = cr.id "
+ "WHERE ce.id = :configurationId AND r.id IS NOT NULL GROUP BY r.id")
Page<ConfigurationReview> findConfigurationReviews(
#Param("configurationId") Long configurationId, Pageable pageable);
Here is the milestone entry in ConfigurationReview dao:
#ManyToOne(fetch = FetchType.LAZY)
#JoinColumn(foreignKey = #ForeignKey(name = "fk_review_milestones_on_milestone_id"))
private Milestone milestone;
With the above changes, it works properly if r.milestone is not null. But when the r.milestone is null, the complete row is ignored in left join.
As a result, if I have 2 r.milestones with data and 2 r.milestones without, the above query returns only two entries instead of four.
The problem appears only if r.milestone is null (because of the ManyToOne relation?). If another property is null, the row is returned properly.
Any idea how can I fix this?

vb.net - Index was outside the bounds of the array

I got a problem in vb.net. By the way I am a newbie. I need your help
what's problem on this error:
My code:
Public Sub load_stockid_monthly_byUP(ByVal type As Integer, ByVal filter As Integer, ByVal input As String)
Dim sqlquery As String = ""
Dim myCommand As New MySqlCommand
Dim myData As MySqlDataReader
Dim x As Integer = 0
Dim where As String = ""
Dim order As String = ""
If filter = 1 Then
where = ""
ElseIf filter = 2 Then
where = " AND r.type =" & input
ElseIf filter = 3 Then
where = " AND s.cat_id =" & input
ElseIf filter = 4 Then
where = " AND (s.desp like '% " & input & " %' OR s.desp like '" & input & " %' OR s.desp like '% " & input & "' OR s.desp = '" & input & "')"
ElseIf filter = 5 Then
where = " AND (s.cat_id = 1 OR s.cat_id = 2 OR s.cat_id = 4 OR s.cat_id = 5 )"
ElseIf filter = 6 Then
where = " AND (s.pallet_id <> 0 OR s.carton_id <> 0)"
order = " ORDER BY carton_id, pallet_id , stock_id"
ElseIf filter = 7 Then
where = " AND (s.pallet_id <> 0)"
order = " ORDER BY pallet_id , stock_id"
ElseIf filter = 8 Then
where = " AND (s.carton_id <> 0)"
order = " ORDER BY carton_id, stock_id"
ElseIf filter = 9 Then
where = " AND (s.uniform_id <> 0)"
order = " ORDER BY uniform_id"
End If
If type = 1 Then
sqlquery = "(SELECT s.id AS id,s.stock_id AS stock_id ,s.packing_id AS packing_id ,s.carton_id AS carton_id, s.pallet_id AS pallet_id, s.desp AS desp,i.unit_price AS unit_price, i.rate AS rate, c.type AS cat, u.unit AS uom, s.currency AS currency, s.uniform_id As uniform_id FROM incoming AS i LEFT JOIN stock AS s ON i.stock_id = s.id LEFT JOIN uom AS u ON s.uom = u.id LEFT JOIN stock_cat AS c ON s.cat_id = c.id LEFT JOIN supplier AS r ON s.supplier_id = r.id WHERE s.active = 1 AND (i.active = 1 OR i.active = 2)" & where & " GROUP BY c.type, s.stock_id , i.unit_price, i.rate ) UNION " _
& "(SELECT s.id AS id,s.stock_id AS stock_id ,s.packing_id AS packing_id ,s.carton_id AS carton_id, s.pallet_id AS pallet_id,s.desp AS desp,i.unit_price AS unit_price, i.rate AS rate, c.type AS cat, u.unit AS uom, s.currency AS currency, s.uniform_id As uniform_id FROM adjust AS i LEFT JOIN stock AS s ON i.stock_id = s.id LEFT JOIN uom AS u ON s.uom = u.id LEFT JOIN stock_cat AS c ON s.cat_id = c.id LEFT JOIN supplier AS r ON s.supplier_id = r.id WHERE s.active = 1 AND i.adjust_qty > 0 AND (i.active = 1 OR i.active = 2)" & where & " GROUP BY c.type, s.stock_id , i.unit_price, i.rate ) " & order
' sqlquery = "SELECT s.id AS id,s.stock_id AS stock_id ,s.desp AS desp,i.unit_price AS unit_price, i.rate AS rate, c.type AS cat, u.unit AS uom, s.currency AS currency FROM incoming AS i LEFT JOIN stock AS s ON i.stock_id = s.id LEFT JOIN uom AS u ON s.uom = u.id LEFT JOIN stock_cat AS c ON s.cat_id = c.id LEFT JOIN supplier AS r ON s.supplier_id = r.id WHERE (i.active = 1 OR i.active = 2)" & where & " GROUP BY c.type, s.stock_id , i.unit_price ORDER BY c.type ,s.stock_id "
ElseIf type = 2 Then
sqlquery = "SELECT s.id AS id,s.stock_id AS stock_id ,s.desp AS desp,n.unit_price AS unit_price, n.rate AS rate, c.type AS cat, u.unit AS uom, s.currency AS currency FROM issue AS i LEFT JOIN stock AS s ON i.stock_id = s.id LEFT JOIN uom AS u ON s.uom = u.id LEFT JOIN incoming AS n ON i.irm_id = n.id LEFT JOIN stock_cat AS c ON s.cat_id = c.id LEFT JOIN supplier AS r ON s.supplier_id = r.id WHERE s.active = 1 AND i.active = 1" & where & " GROUP BY c.type, s.stock_id , n.unit_price ORDER BY c.type ,s.stock_id"
End If
stock_id_count = 0
ConnectmyDB()
myCommand.Connection = conn
myCommand.CommandText = sqlquery
myData = myCommand.ExecuteReader
If myData.HasRows = False Then
x = 1
Else
While myData.Read
data(x, 0) = myData.GetInt32("id")
data(x, 1) = myData.GetString("stock_id")
data(x, 2) = myData.GetString("desp")
data(x, 8) = myData.GetString("unit_price")
data(x, 9) = myData.GetString ("rate")
data(x, 12) = myData.GetString("cat")
data(x, 14) = myData.GetString("uom")
data(x, 16) = myData.GetString("packing_id")
x = x + 1
End While
End If
DisconnectDatabase()
stock_id_count = x
End Sub 'closing stock unit price
I get the error:
Index was outside the bounds of the array for that code 'data(x, 0) = myData.GetInt32("id")'
How to fix that?
This is what i get when run in program:
************** Exception Text **************
System.IndexOutOfRangeException: Index was outside the bounds of the array.
at Purchasing.mdlStoreBalance.load_stockid_monthly_byUP(Int32 type, Int32 filter, String input)
at Purchasing.frmStockBalanceReport.bt_preview_Click(Object sender, EventArgs e)
Thank you
Where is data(x,?) defined? You fill data within a while loop, but there is no checking to see if the while loop overruns the defined bounds.
I also can't tell how much data you expect to read. This will influence the run-time for the while loop and how high x is expected to get.
(would have asked this as a comment, but my rep is not yet high enough in this form).
As an aside, the checking of filter can be done in a select case statement. This will allow you to double check that you have covered where and order consistently. Also, as a coding convention, naming variables exactly the same as a one of your keywords (in this case a SQL keyword) can hide simple errors. Calling them something like whereStmnt and orderStmnt might help.

Union causing Firebird 2.5 query to fail

This SQL (Firebird 2.5, Dialect 1) query works fine when I run it in Database Workbench, but it fails when I run it under IBO Console with:
count of column list and variable list do not match.
These two queries run successfully if I run them alone under IBO console, so I'm inferring that the problem is because of the "Union." The number and types of columns match for the two queries--both return string, smallint, string (IBO console regards this as a memo), string--so Union should be valid (and DB Workbench finds it so). Thinking that maybe the length of the data was different, I tried casting the third column as a VarChar(500) but that didn't help. Looking for ideas as to why this doesn't work since the part of our app that is executing the query is apparently choking on this in the same way that IBO Console is.
Select QBI.TXNID as ID,
Cast (1 as SmallInt) as TransactionType,
("Invoice " || QBI.REFNUMBER || ": $" || round(QBI.SUBTOTAL, 2) || " on " || QBI.TXNDATE || " for " || QBI.CUSTOMERREF_FULLNAME) as description,
case
when (QBI.CLASSREF_LISTID = "") then "Invoice has no class in Quickbooks"
else "Invoice class doesn't match any dept on job " || JA.JOBID
end as Problem
from QBINVOICE QBI
Join JOBACCOUNTINGID JA
on QBI.CUSTOMERREF_LISTID = JA.jobaccountingid
and QBI.SOURCEID = JA.SOURCEID
left Join CHARTOFACCOUNTS CA
on (CA.qblistid = QBI.CLASSREF_LISTID and CA.qbsourceID = QBI.SOURCEID)
and CA.CHARTACCOUNTTYPE = "SYSTEM"
and CA.CHARTFETCH = "Y"
left Join DEPARTMENTJOB DJ
on JA.JOBID = DJ.JobID
and DJ.departmentID = CA.DEPARTMENTID
where DJ.DEPARTMENTID is null
and QBI.TXNDATE >= "02/01/2017"
union all
select
QBELD.TXNLINEID as ID,
Cast (2 as SmallInt) as TransactionType,
QBB.VENDORREF_FULLNAME || " bill on " || QBB.TXNDATE || ": $" || round(QBELD.AMOUNT, 2) || " " || QBELD.ACCOUNTREF_FULLNAME || " expense" as description,
case
when (QBELD.CLASSREF_LISTID = "") then "Expense has no class in Quickbooks"
else "Expense class doesn't match any dept on job " || JA.JOBID
end as Problem
from QBTxnExpenseLineDetail QBELD
JOIN QBBILL QBB
on QBELD.TXNLINEID = QBB.TXNID
and QBELD.SOURCEID = QBB.SOURCEID
Join JOBACCOUNTINGID JA
on QBELD.CUSTOMERREF_LISTID = JA.jobaccountingid
and QBELD.SOURCEID = JA.SOURCEID
left Join CHARTOFACCOUNTS CA
on (CA.qblistid = QBELD.CLASSREF_LISTID and CA.qbsourceID = QBELD.SOURCEID)
and CA.CHARTACCOUNTTYPE = "SYSTEM"
and CA.CHARTFETCH = "Y"
left Join DEPARTMENTJOB DJ
on JA.JOBID = DJ.JobID
and DJ.departmentID = CA.DEPARTMENTID
where DJ.DEPARTMENTID is null
and QBB.TXNDATE >= "02/01/2017"

Update a boolean field as criteria using Count inside IF

I have 2 tables called t_task and t_task_details in MS Access
t_task has 3 columns: task_id, task_description, task_status (task_status column is Yes/No column while the rest are Short Text)
t_task_details also has 3 columns: task_id, task_date and done (done is also Yes/No)
Every task is linked to task_details via task_id.
I want update task_status to Yes / True if ALL task_details.done are Yes / True
I have tried this, but unfortunately it's not working:
UPDATE t_task
INNER JOIN t_task_details ON t_task.task_id = t_task_details.id
SET t_task.task_status = IIF(Count(t_task_details.done) = 0, True, False)
WHERE t_task_details.done = False
I think you can use a query like this:
UPDATE t_task
SET t_task.task_status = true
WHERE (SELECT COUNT(*)
FROM t_task_details
WHERE t_task_details.task_id = t_task.id) =
(SELECT COUNT(*)
FROM t_task_details
WHERE t_task_details.task_id = t_task.id
AND t_task_details.done = True)
I don't test it yet.
Note that this will update status of tasks that has no any details, If you want to remove them from update you can add this to the query:
...
AND EXISTS(SELECT 1 FROM t_task_details
WHERE t_task_details.task_id = t_task.id);
UPDATE :
If you want to update status to false for other records, I suggest you to use this query instead:
UPDATE t_task
SET t_task.task_status = IIF(
(SELECT COUNT(*)
FROM t_task_details
WHERE t_task_details.task_id = t_task.id) =
(SELECT COUNT(*)
FROM t_task_details
WHERE t_task_details.task_id = t_task.id
AND t_task_details.done = True), true, false)
WHERE EXISTS(SELECT 1 FROM t_task_details
WHERE t_task_details.task_id = t_task.id);
You can also use DCount and DSum:
UPDATE
t_task
SET
t_task.task_status =
(DCount("*", "t_task_details", "[task_id] = " & t_task.id & "") =
Abs(DSum("[done]","t_task_details", "[task_id] = " & t_task.id & "")))
If key is not numeric:
(DCount("*", "t_task_details", "[task_id] = '" & t_task.id & "'") =
Abs(DSum("[done]","t_task_details", "[task_id] = '" & t_task.id & "'")))

vb.net - using case select query in sql for jtable

If anyone knows how to use case in query for jtable, pls take a look my code.
Dim batch_status As String = " case when status = 0 then 'Created' when status = 1 then 'Scanning' when status = 2 then 'Scan Saved' end as status"
cmd.CommandText = "SELECT * FROM ( SELECT ROW_NUMBER() OVER ( ORDER BY " & jtSorting & " ) AS RowNum, batch_id, batch_name, date_created, profile_id, total_page, " & batch_status & ", First_ScanID, file_id " & _
" FROM [ip_ent_site].[dbo].[tbl_batch] WHERE STATUS IN (0,1,2) ) AS RowConstrainedResult " & _
" WHERE RowNum >= #jtStartIndex AND RowNum < #jtEndIndex ORDER BY RowNum ; "
if i use like this, it is working:
Dim batch_status As String = "status"
but with case, not.
whats problem here?
another part of code:
If dt.Rows.Count > 0 Then
students = (From item In dt.AsEnumerable() Select New Class1 With { _
.No = Convert.ToInt32(item(1)), _
.batch_id = Convert.ToInt64(item(2)), _
.batch_name = DirectCast(item(3), String), _
.date_created = item(4).ToString, _
.profile_id = Convert.ToInt32(item(5)), _
.total_page = Convert.ToInt32(item(6)), _
.status = Convert.ToInt32(item(7)), _
.First_ScanID = Convert.ToInt32(item(8)), _
.file_id = CheckDBNullInteger(item(9)) _
}).ToList()
End If
Use your declare statement like below.
Dim batch_status As String = " case when status = 0 then ''Created'' when status = 1 then ''Scanning'' when status = 2 then ''Scan Saved'' end as status"
may be the problem with #jtStartIndex AND #jtEndIndex.
Just found, change .status = Convert.ToInt32(item(7)) to .status = item(7).ToString,
displaying in Jtable is quite different