I have two queries.
The first one is..
INSERT INTO balik
( balik_date,
balik_time,
balik_cardID,
balik_status,
balik_type )
select
current_date(),
'00:00:00',
L_CardID,
'BELUM BALIK',
L_Type
FROM
logdetail t1
LEFT JOIN balik t2
ON t1.L_CardID = t2.balik_cardID
WHERE
t1.L_Type = 'IN'
and t1.L_Date = current_date()
AND t2.balik_cardID IS NULL"
and another one is..
UPDATE balik blk
INNER JOIN logdetail ld
ON blk.balik_cardID = ld.L_CardID
and blk.balik_date = current_date()
SET
blk.balik_status = 'SUDAH BALIK',
blk.balik_type = 'OUT',
blk.balik_time = ld.L_Time
WHERE
ld.L_Type = 'OUT'
and ld.L_Date = current_date()
My problem is that when I execute the first and second query nothing happens unless I delete all records in my table beforehand. In that case both queries are executed and work like a charm.
Why is this happening?
From what I remember, you can't do an insert into a table that is a result of a query that may be an impact of what you are inserting... So, it MIGHT help if the select was "wrapped" inside another layer so the inner query is completely processed FIRST and thus not impacted by the inserts.
INSERT INTO balik
( balik_date,
balik_time,
balik_cardID,
balik_status,
balik_type )
select
PreQuery.newDate,
PreQuery.newTime,
PreQuery.newCardID,
PreQuery.newStatus,
PreQuery.newType
from
( select
current_date() newDate,
'00:00:00' newTime,
L_CardID newCardID,
'BELUM BALIK' newStatus,
L_Type newType
FROM
logdetail t1
LEFT JOIN balik t2
ON t1.L_CardID = t2.balik_cardID
WHERE
t1.L_Type = 'IN'
and t1.L_Date = current_date()
AND t2.balik_cardID IS NULL" ) PreQuery
I would alter the syntax on the update to more closely match that of the SQL Syntax per documentation... list the tables comma separated, then apply join conditions in the WHERE clause
UPDATE balik blk, logdetail ld
SET
blk.balik_status = 'SUDAH BALIK',
blk.balik_type = 'OUT',
blk.balik_time = ld.L_Time
WHERE
blk.balik_cardID = ld.L_CardID
and blk.balik_date = current_date()
and ld.L_Type = 'OUT'
and ld.L_Date = current_date()
Yeah, essentially the same thing, but might be interpretation issues.
Related
When I add the nested query for invCount, my query time goes from .03 sec to 14 sec. The query works and I get correct values, but it is very, very slow in comparison. Is that just because I have to many conditions in that query? When I take it out and still have the second nested query, the time is still .03 secs. There is clearly something about the first nested query the database doesn't like, but I am not seeing what it is. I have a foreign key set for all the inner join lines too. Any help or ideas would be appreciated.
SELECT a.*,
f.name,
f.partNumber,
f.showInAdminStore,
f.showInPublicStore,
f.productImage,
r.mastCatID,
(SELECT COUNT(b.inventoryID)
FROM storeInventory b
INNER JOIN events c ON c.eventID = b.eventID
WHERE b.pluID = a.pluID
AND b.listPrice = a.listPrice
AND b.unlimitedQty = a.unlimitedQty
AND (b.packageID = a.packageID OR (b.packageID IS NULL AND a.packageID IS NULL))
AND b.orderID IS NULL
AND c.isOpen = '1'
AND b.paymentTypeID <= '2'
AND (b.inCart < '$cartTime' OR b.inCart IS NULL) ) AS invCount,
(SELECT COUNT(x.inventoryID)
FROM storeInventory x
WHERE x.packageID = a.inventoryID) AS packageCount
FROM storeInventory a
INNER JOIN storePLUs f ON f.pluID = a.pluID
INNER JOIN storeCategories r ON r.catID = f.catID
INNER JOIN events d ON d.eventID = a.eventID
WHERE a.storeFrontID = '1'
AND a.orderID IS NULL
AND a.paymentTypeID <= '2'
AND d.isOpen = '1'
GROUP BY a.packageID, a.unlimitedQty, a.listPrice, a.pluID
Table from query output
UPDATE: 12/12/2022
I changed the line checking the packageID to "AND (b.packageID <=> a.packageID)" as suggested and that cut my query time down to 7.8 seconds from 14 seconds. Thanks for the pointer. I will definitely use that in the future for NULL comparisons.
using "count(*)" took about half a second off. When I take the first nested query out, it drops down to .05 seconds even with the other nested queries in there, so I feel like there is still something causing issues. I tried running it without the other "AND (b.inCart < '$cartTime' OR b.inCart IS NULL)" line and that did take about a second off, but no where what I was hoping for. Is there an operand that includes NULL on a less than comparison? I also tried running it without the inner join in the nested query and that didn't change much at all. Of course removing any of that, throughs the values off and they become incorrect, so I can't run it that way.
Here is my current query setup that still pulls correct values.
SELECT a.*,
f.name,
f.partNumber,
f.showInAdminStore,
f.showInPublicStore,
f.productImage,
r.mastCatID,
(SELECT COUNT(*)
FROM storeInventory b
INNER JOIN events c ON c.eventID = b.eventID
WHERE b.pluID = a.pluID
AND b.listPrice = a.listPrice
AND b.unlimitedQty = a.unlimitedQty
AND (b.packageID <=> a.packageID)
AND b.orderID IS NULL
AND c.isOpen = '1'
AND b.paymentTypeID <= '2'
AND (b.inCart < '$cartTime' OR b.inCart IS NULL) ) AS invCount,
(SELECT COUNT(x.inventoryID)
FROM storeInventory x
WHERE x.packageID = a.inventoryID) AS packageCount
FROM storeInventory a
INNER JOIN storePLUs f ON f.pluID = a.pluID
INNER JOIN storeCategories r ON r.catID = f.catID
INNER JOIN events d ON d.eventID = a.eventID
WHERE a.storeFrontID = '1'
AND a.orderID IS NULL
AND a.paymentTypeID <= '2'
AND d.isOpen = '1'
GROUP BY a.packageID, a.unlimitedQty, a.listPrice, a.pluID
I am not familiar with the term 'Composite indexes' Is that something different than these?
Screenshot of ForeignKeys on Table a
I think
AND (b.packageID = a.packageID
OR (b.packageID IS NULL
AND a.packageID IS NULL)
)
can be simplified to ( https://dev.mysql.com/doc/refman/8.0/en/comparison-operators.html#operator_equal-to ):
AND ( b.packageID <=> a.packageID )
Use COUNT(*) instead of COUNT(x.inventoryID) unless you check for not-NULL.
The subquery to compute packageCount seems strange; you seem to count inventories but join on packages.
The need to reach into another table to check isOpen is part of the performance problem. If eventID is not the PRIMARY KEYforevents, then add INDEX(eventID, isOpen)`.
Some other indexes that may help:
a: INDEX(storeFrontID, orderID, paymentTypeID)
a: INDEX(packageID, unlimitedQty, listPrice, pluID)
b: INDEX(pluID, listPrice, unlimitedQty, orderID)
f: INDEX(pluID, catID)
r: INDEX(catID, mastCatID)
x: INDEX(packageID, inventoryID)
After OP's Update
There is no way to do (x<y OR x IS NULL) except by switching to a UNION. In your case, it is pretty easy to do the conversion. Replace
( SELECT COUNT(*) ... AND ( b.inCart < '$cartTime'
OR b.inCart IS NULL ) ) AS invCount,
with
( SELECT COUNT(*) ... AND b.inCart < '$cartTime' ) +
( SELECT COUNT(*) ... AND b.inCart IS NULL ) AS invCount,
Revised indexes:
storePLUs:
INDEX(pluID, catID)
storeCategories:
INDEX(catID, mastCatID)
events:
INDEX(isOpen, eventID)
storeInventory:
INDEX(pluID, listPrice, unlimitedQty, orderID, packageID)
INDEX(pluID, listPrice, unlimitedQty, orderID, inCart)
INDEX(packageID, inventoryID)
INDEX(storeFrontID, orderID, paymentTypeID)
I would like to find out what causes the slow execution of my MySQL query here. It's 1 row fetched in 0.0017s (3.6215s) How can i optimize this?
SELECT hadmlog.hpercode as 'HOSPITAL NUMBER', FLOOR (hadmlog.patage) as 'AGE', CONCAT (hperson.patlast, ', ', hperson.patfirst, ' ',hperson.patmiddle) as 'PROFILE', hcity.ctyname as 'DISTRICT', hadmlog.disdate as 'DISCHARGED DATE'
FROM hadmlog
INNER JOIN hperson ON hadmlog.hpercode=hperson.hpercode
INNER JOIN haddr ON hadmlog.hpercode=haddr.hpercode
INNER JOIN hcity ON haddr.ctycode=hcity.ctycode
WHERE hadmlog.patage BETWEEN '1' AND '4'
AND hperson.patsex = 'M'
AND DATE(hadmlog.disdate) = DATE(curdate())
AND haddr.haddrdte = ( select max(haddrdte)
from haddr
where haddr.hpercode = hperson.hpercode )
ORDER BY Profile;
First, fix the query:
SELECT al.hpercode as HOSPITAL_NUMBER, FLOOR(al.patage) as AGE,
CONCAT_WS(' ', p.patlast, p.patfirst, p.patmiddle) as PROFILE,
c.ctyname as DISTRICT, al.disdate as DISCHARGED_DATE
FROM hadmlog al JOIN
hperson p
ON al.hpercode = p.hpercode JOIN
haddr a
ON al.hpercode = a.hpercode JOIN
hcity c
ON a.ctycode = c.ctycode
WHERE al.patage BETWEEN 1 AND 4 AND
p.patsex = 'M' AND
al.disdate >= curdate() AND
al.disdate < curdate() + INTERVAL 1 day AND
a.haddrdte = (select max(h2.haddrdte)
from haddr h2
where h2.hpercode = p.hpercode
)
ORDER BY Profile;
Some of the changes are cosmetic (such as the table aliases and CONCAT_WS()). The more relevant changes are:
patage appears to be a number, so make the comparisons numbers. Strings can impede the optimizer.
date(disdate) can also impede the optimizer.
Then, for this query, I am guessing that you want an indexes:
hadmlog(disdate, patage)
And then you want indexes on the JOIN keys used for the other tables.
How do I include SUM((pm.Quantity * bl.TotalQty)) AS NextBOMItemCount WHERE projectbomlist.ParentPartNum = bl.PartNum?
The data should not be changed, the same data should be retrieved, the however additional column has to be included.
VIEW: `NEWprojectBOMItemCount
select
`pm`.`ProjectCode` AS `ProjectCode`,
`bl`.`PartNum` AS `PartNum`,
sum((`pm`.`Quantity` * `bl`.`TotalQty`)) AS `BOMItemCount`,
`bl`.`mp` AS `mp`,
`p`.`complete` AS `complete`,
`bl`.`RMInd` AS `RMInd`,
`bl`.`M_PartNum` AS `M_PartNum`
from
(
(`projectmachine` `pm` join `projectbomlist` `bl`)
join `projects` `p`
)
where
(
(`pm`.`MachineListID` = `bl`.`MachineListID`)
and (`pm`.`ProjectCode` = `bl`.`ProjectCode`)
and (`pm`.`ProjectCode` = `p`.`ProjectCode`)
and (`p`.`AfterProjectHeirarchyInd` = 'Y')
)
and and pm.ProjectCode = 'AB212323'
group by
`pm`.`ProjectCode` ,
`bl`.`PartNum`
order by
`pm`.`ProjectCode` ,
`bl`.`PartNum`
Or, another option can be, please consider above view used in below query, please suggest changes to the below query as shown above (repeating here)
`sum((pm.Quantity * bl.TotalQty)) AS NextBOMItemCount where projectbomlist.ParentPartNum = bl.PartNum` - in place of `(select-NextBOMItemCount)`?
Please see PBLH.ParentPartNum is the column that I should compare with BL.ProjectCode to get NextBOMItemCount value.
QUERY calling view: NEWprojectBOMItemCount
Select
BL.PartNum PartNumber,
PBLH.ParentPartNum NextBOM,
(select-NextBOMItemCount),
BOMItemCount TotalQty,
PL.Description,
BL.MP as PartType,
PL.Vendor,
PL.QBType
from
NEWprojectBOMItemcount BL,
bomwiz.partslist PL,
bomwiz.projectbomlistheirarchy PBLH
Where
BL.PartNum = PL.PartNum
And BL.PartNum = PBLH.PartNum
And BL.ProjectCode = PBLH.ProjectCode
And BL.projectCode = 'AB212323'
Order By PartNumber
I think that you are looking for conditional aggregation. Your requirement could be expressed as follows:
SUM(
CASE WHEN blh.ParentPartNum = bl.PartNum
THEN pm.Quantity * bl.TotalQty
ELSE 0
END
) AS NextBOMItemCount
Let me pinpoint other issues with your query:
you have unwanted parentheses all around, and I am suspicious about the syntax of the JOINs ; you need to move conditions to the ON clause of the relevant JOIN.
every non-aggregated column must appear in the GROUP BY clause - you have missing columns there
backquotes are usually not needed
Here is an updated version of the query:
SELECT
pm.ProjectCode AS ProjectCode,
bl.PartNum AS PartNum,
SUM(pm.Quantity * bl.TotalQty) AS BOMItemCount,
SUM(
CASE WHEN blh.ParentPartNum = bl.PartNum
THEN pm.Quantity * bl.TotalQty
ELSE 0
END
) AS NextBOMItemCount,
bl.mp AS mp,
p.complete AS complete,
bl.RMInd AS RMInd,
bl.M_PartNum AS M_PartNum
FROM
projectmachine AS pm
INNER JOIN projectbomlist AS bl
ON pm.MachineListID = bl.MachineListID
AND pm.ProjectCode = bl.ProjectCode
INNER JOIN join projects AS p
ON pm.ProjectCode = p.ProjectCode
AND p.AfterProjectHeirarchyInd = 'Y'
INNER JOIN projectbomlistheirarchy blh
ON bl.ProjectCode = blh.ProjectCode
WHERE
pm.ProjectCode = 'AB212323'
GROUP BY
pm.ProjectCode,
bl.PartNum,
bl.mp,
p.complete,
bl.RMInd,
bl.M_PartNum
ORDER BY
pm.ProjectCode,
bl.PartNum
I need to set "dph" in this table "Strobjednavka", but i donĀ“t know whats wrong there. Please help :).
Here is my SQL script:
UPDATE STRObjednavka as o SET dph = (
SELECT dph FROM STRCena WHERE
menuKodCode =
(SELECT menuKodCode FROM STRMenu WHERE
id = o.menuId
)
AND
skupinaId =
(SELECT stravGroupId FROM grups1 WHERE
PKey =
(SELECT SGroup FROM users1 WHERE
PKey = o.userId
)))
WHERE o.price > 0 AND `date` > '2015-01-28 13:52:36' AND dph = 0;
SQL say : SQL error 1242: Subquery returns more than 1 row
You can able to update with below script, but you need to check whether update is correct or not, If you give some sample data then it will be easy to track the problem.
UPDATE STRObjednavka as o SET dph = (
SELECT max(dph) FROM STRCena WHERE
menuKodCode =
(SELECT max(menuKodCode) FROM STRMenu WHERE
id = o.menuId
)
AND
skupinaId =
(SELECT max(stravGroupId) FROM grups1 WHERE
PKey =
(SELECT max(SGroup) FROM users1 WHERE
PKey = o.userId
)))
WHERE o.price > 0 AND `date` > '2015-01-28 13:52:36' AND dph = 0;
Unfortunately, MySQL doesn't allow you to LIMIT a subquery. Depending on your use case you can add MIN or MAX to your subqueries. Here it is with MINs in all the subqueries:
UPDATE STRObjednavka as o SET dph = (
SELECT MIN(dph) FROM STRCena WHERE
menuKodCode =
(SELECT MIN(menuKodCode) FROM STRMenu WHERE
id = o.menuId
)
AND
skupinaId =
(SELECT MIN(stravGroupId) FROM grups1 WHERE
PKey =
(SELECT MIN(SGroup) FROM users1 WHERE
PKey = o.userId
)))
WHERE o.price > 0 AND `date` > '2015-01-28 13:52:36' AND dph = 0;
Although you really only need to add it to the subquery that's returning more than one row.
Your first problem is that you're writing '.... = (SELECT .... )'. Since you're using the equality operator, you're asking SQL to assign an entire column of values to a single cell. Change your equality operators before your subqueries to IN operators.
You probably should use a different query pattern.
You have this sort of thing in your query, in several places.
WHERE menuKodCode = /* !! might generate error 1242 */
(SELECT menuKodCode FROM STRMenu WHERE id = o.menuId)
There's no guarantee that your inner query won't return more than one row, and when it does, MySQL throws error 1242.
SQL works wiith sets of values. If you used IN instead of =, your query would work.
WHERE ... menuKodCode IN
(SELECT menuKodCode FROM STRMenu WHERE id = o.menuId)
But you should figure out whether that logic is correct. If I were you I'd do a whole bunch of SELECT operations to test it before doing UPDATE.
The following is the MS Sql server Update statement
Update
HC_TranDetails
SET
InsPayments = (SELECT IsNull(SUM(ISNULL(CreditAmount,0)),0) From HC_TranDetails TDS
Where TDS.TransactionType = 2
AND TDS.ClaimNo = TD.ClaimNo
AND TDS.LineItemNo = TD.LineItemNo
AND IsNull(TDS.InsPlanRowID,'') <> ''
AND TDS.ReverseEntry <> 1 ),
Adjustments = (SELECT IsNull(SUM(ISNULL(CreditAmount,0)),0) From HC_TranDetails TDS
Where TDS.TransactionType = 8
AND TDS.ClaimNo = TD.ClaimNo
AND TDS.LineItemNo = TD.LineItemNo
AND IsNull(TDS.InsPlanRowID,'') <> ''
AND TDS.ReverseEntry <> 1 ),
FROM
HC_TranDetails TD
Now i am trying the same kind of statement in mysql as follows
UPDATE claimdetails SET balanceAmount = (SELECT IFNULL(SUM(IFNULL(debitamount,0)) - SUM(IFNULL(creditamount,0)),0)
FROM claimdetail CD WHERE CD.claimID = CDS.claimID)
FROM ClaimDetail CDS
But it is showing as syntax Error near 'From ClaimDetail CDS' at line 4
MySQL is squeamish about updates on the same table. The easy fix is to include an extra level of subquery. The proper fix, though, is to use a join
UPDATE claimdetails join
(select claimid, IFNULL(SUM(IFNULL(debitamount,0)) - SUM(IFNULL(creditamount,0)),0) as val
from ClaimDetails
group by claimid
) agg
on claimdetails.claimid = agg.claimid
SET balanceAmount = agg.val;
You can join the table you want to update with a subquery that calculates the balance for each claimid on the other table.
By using LEFT JOIN, it will update all records on table claimdetails. A value of 0 will be updated to any non existent claimid on the subquery.
UPDATE claimdetails a
LEFT JOIN
(
SELECT claimID,
SUM(IFNULL(debitamount, 0)) - SUM(IFNULL(creditamount,0)) bal
FROM claimdetail
GROUP BY claimID
) b ON a.claimID = b.claimID
SET a.balanceAmount = IFNULL(b.bal, 0)