MYSQL insert multiple row from select statement - mysql

I have results from select statement,but i need to insert the result into another table.How to archieve this on mysql or php?
Select statement :
SELECT a.*,MONTH(bd.tarikh) bulan,tahun
FROM
(
SELECT bl_ic_pesawah ic,bl_name name,bl_musim musim,bl_zon_id zon,bl_nettWeight nettWeight,
CASE
WHEN bl_nettWeight BETWEEN be_rangef AND be_ranget THEN be_quantity
WHEN bl_nettWeight >= be_morethan THEN be_quantity_1
WHEN bl_nettWeight = be_morethan_sws THEN be_quantity_sws
ELSE NULL END AS layak,
be.be_date_from date_from,be_date_to date_to
FROM b_ledger
LEFT JOIN b_entitle be ON bl_musim = be_season AND bl_zon_id = be_zid
WHERE be.be_status='Buka' AND bl_id = 1
) a
LEFT JOIN b_date bd ON bd.tarikh BETWEEN a.date_from AND a.date_to
GROUP BY MONTH(bd.tarikh),a.ic
After inserted into table it will be something like this:

You could use select in insert query, With your task:
INSERT INTO other_table (ic ,name ,musim ,zon ,nettWeight ,layak ,date_from ,date_to)
SELECT a.ic ,a.name ,a.musim ,a.zon ,a.nettWeight ,a.layak ,a.date_from ,a.date_to
,MONTH(bd.tarikh) bulan,tahun
FROM
(
SELECT bl_ic_pesawah ic,bl_name name,bl_musim musim,bl_zon_id zon,bl_nettWeight nettWeight,
CASE
WHEN bl_nettWeight BETWEEN be_rangef AND be_ranget THEN be_quantity
WHEN bl_nettWeight >= be_morethan THEN be_quantity_1
WHEN bl_nettWeight = be_morethan_sws THEN be_quantity_sws
ELSE NULL END AS layak,
be.be_date_from date_from,be_date_to date_to
FROM b_ledger
LEFT JOIN b_entitle be ON bl_musim = be_season AND bl_zon_id = be_zid
WHERE be.be_status='Buka' AND bl_id = 1
) a
LEFT JOIN b_date bd ON bd.tarikh BETWEEN a.date_from AND a.date_to
GROUP BY MONTH(bd.tarikh),a.ic

Get the result into an array.. then opening another database connection to create a new table..then INSERT sql using new database_table_name

Related

MYSQL SELECT is slow when crossing multiple tables

I have a mysql query which is to return the only 1 record that need to cross multiple table. However, the mysql query is slow when executing.
Query:
SELECT *,
(SELECT TreeName FROM sys_tree WHERE TreeId = Mktg_Unit_Booking.ProjectLevelId) AS PhaseName,
(CASE WHEN ProductType = 'U' THEN (SELECT UnitNo FROM prop_unit pu WHERE pu.UnitId = mktg_unit_booking.UnitId)
ELSE (SELECT BayNo FROM prop_car_park pcp WHERE pcp.CarParkId = UnitId) END) AS UnitNo,
(SELECT CustomerName FROM mktg_customer mc WHERE mc.CustomerId = mktg_unit_booking.CustomerId) AS CustomerName
FROM Mktg_Unit_Booking
WHERE IsDeleted <> '1' AND IsApproved = '1'
AND UnitId = 1110 AND ProductType = 'U'
ORDER BY UnitNo
I have run EXPLAIN in the query and I got this:
Any other suggestion on how to improve the speed of the query?
Thank you!
you are doing the cross product, instead of that you should use join.
Don't use sub-queries in select statement instead use proper join on Mktg_Unit_Booking in after from statement.
you query should something look like :
select
sys_tree.TreeName AS PhaseName,
case
WHEN Mktg_Unit_Booking.ProductType = 'U' then prop_unit.UnitNo
else prop_car_park.BayNo
end as UnitNo,
mktg_customer.CustomerName AS CustomerName
FROM Mktg_Unit_Booking
left join sys_tree on sys_tree.TreeId = Mktg_Unit_Booking.ProjectLevelId
left join prop_unit on prop_unit.UnitId = Mktg_Unit_Booking.UnitId
left join prop_car_park on prop_car_park.CarParkId = Mktg_Unit_Booking.UnitId
left join mktg_customer on mktg_customer.CustomerId = Mktg_Unit_Booking.CustomerId
WHERE IsDeleted <> '1' AND IsApproved = '1'
AND UnitId = 1110 AND ProductType = 'U'
ORDER BY UnitNo;
I have assumed that each table consists of only 1 matching tuple. If there are more then your logic needs to be modified.

mysql update statement using the from clause on the same table

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)

Select only having count=2

--This is the code
create table #Test (Systemtraceno nvarchar(50),Bin nvarchar(50),SwitchCode nvarchar(50),
SwitchDesc nvarchar(50),[Description] nvarchar(50))
insert into #Test
select SystemTraceno , Bin,SwitchCode,SwitchDesc,[Description]
from(
select A.SystemTraceNo, A.BIN,'' SwitchCode, '' SwitchDesc,''[Description]
from ATM035 A
where a.TranDate = '20130924' and MsgType = '0210' and TerminalID = '08880001'
and A.ProcessCode in ('011000','012000','013000') and A.ResponseCode = '0000' and A.BIN <> '502265'
--group by A.SystemTraceNo, A.BIN
)x
group by SystemTraceNo,BIN,SwitchCode,SwitchDesc,[Description]
having COUNT(SystemTraceNo)=2
update #Test set SwitchCode = (select top 1 SwitchCode from ATM027 where Bin = #Test.Bin )
update #test set SwitchDesc = (select switchname from ATM016 where SwitchCode = #test.switchcode)
update #test set [Description] = (Select top 1 Description from ATM027 where BIN = #Test.Bin )
Select * from #test order by SwitchDesc asc
drop table #test
--,'301000','302000','303000'
i just wanted to select rows having SystemTrace number count = 2.I earlier had problems with aggregation and now this.Hoping you could help me out.Thanks in advance
#Royi: actually, i think it should be
select customers.customerId , count(orders.id) as num
from customers join orders on custumers.Id = orders.customerId
group by customers.customerId
having num=2
I'm not going to get into your code but this is how it should be :
select customers.customerId
from customers join orders on custumers.Id = orders.customerId
group by customers.customerId
having count(orders.id)=2
See section 2 here : (section 1 is for the one who said it's possible).
http://i.stack.imgur.com/aE2M3.png
where systemtraceno in (select systemtraceno from #Test group by systemtraceno having count(systemtraceno) = 2)
I thin the problem is at
group by SystemTraceNo
when you want to use
COUNT(SystemTraceNo)=2
In short your insert code should be like this:
insert into #Test
select A.SystemTraceno , A,Bin,'' SwitchCode,'' SwitchDesc,'' [Description]
from ATM035 A
where a.TranDate = '20130924' and MsgType = '0210' and TerminalID = '08880001'
and A.ProcessCode in ('011000','012000','013000') and A.ResponseCode = '0000' and A.BIN <> '502265'
group by A.BIN
having COUNT(SystemTraceNo)=2

SQL update table using select from and multiple joins

Here are the relevant columns of my tables
bia_panels ( id, sign_id, value, project_id )
bia_clients ( id, name )
bia_projects ( id, name, client_id, city_id )
bia_cities ( id, name )
I am attempting to update the bia_panels.project_id to the bia_projects.id where the bia_panels.value = bia_clients.name and the panels.project_id =000 and the value is not blank of course I must use multiple joins to get there
-- UPDATE
SELECT * FROM
`bia_panels` AS t1
JOIN bia_clients AS t2
ON t1.value = t2.name
JOIN bia_projects AS t3
ON t2.id = t3.client_id
-- SET t1.project_id = t3.id
-- WHERE t1.value<>'' AND t1.project_id = '000'
WHERE t1.value <>''
The problem is that this is not giving me the correct results (my project ids are not correct somewhere in the joins multiple results are returned so they break
I know that once I am able to get the select portion correct I can use an update
For example there may be multiple panels where the value=client.name but not all of them are the same project ID
and bia_panels.ID = bia_panels.project_id
join condition is missing in your select query, this should be added like
JOIN bia_projects ON bia_clients.id = bia_projects.client_id and bia_panels.ID = bia_panels.project_id
following query should give right output
SELECT sign_id, value, left(sign_id, 3) AS city_ID ,
bia_clients.id AS 'client id', bia_projects.id AS proj_id , bia_cities.id
FROM bia_panels
JOIN bia_clients ON bia_panels.value = bia_clients.name
JOIN bia_projects ON bia_clients.id = bia_projects.client_id and bia_panels.ID = bia_panels.project_id
JOIN bia_cities ON bia_projects.city_id = bia_cities.id WHERE bia_panels.value<>'' AND bia_panels.project_id = '000' ORDER BY value
I would little bit reorganize your query into UPDATE query:
UPDATE bia_panels p, bia_clients c, bia_projects t
SET p.project_id=t.id
WHERE p.value=c.name
AND t.client_id=c.id
AND p.project_id=''

mySQL Query get record that dont match

I have an sql query that I wish to add another condition to but I cant seem to get it work. The query is simple enough:
SELECT DISTINCT monthly_returns.company_id
FROM monthly_returns, paidreturns
WHERE monthly_returns.company_id = paidreturns.company_id
AND paidreturns.month = '$cdate'
AND paidreturns.paid =0
However I wish to get the records also from the monthly_returns that have not record at all in paidreturns for the give date. I know it would be something like this
SELECT *
FROM monthly_returns
WHERE monthly_returns NOT IN (SELECT * FROM paidreturns WHERE paidreturns.month = '$cdate')
paidreturns.paid =0 is where the bill has not been paid, but equally if there is no record for that date in paidreturns then the bill is also not paid.
The schema
paidreturns table
-id
-company_id
-paid
-month
-total
monthly_returns table
-id
-company_id
-wage_totals
-month
Try this:
SELECT
DISTINCT monthly_returns.company_id
FROM
monthly_returns
LEFT JOIN
paidreturns
ON monthly_returns.company_id = paidreturns.company_id
AND monthly_returns.month = paidreturns.month
WHERE
monthly_returns.month = '$cdate'
AND
(
paidreturns.paid = 0
OR
paidreturns.company_id IS NULL
);
Using a LEFT JOIN, you can find all records from monthly_returns, regardless of whether they matched an entry from paidreturns.
Then, by adding paidreturns.company_id IS NULL to the WHERE clause, you include those unmatched entries in your query.
select company_id
from
(
(
SELECT DISTINCT monthly_returns.company_id
FROM monthly_returns, paidreturns
WHERE monthly_returns.company_id = paidreturns.company_id
AND paidreturns.month = '$cdate'
AND paidreturns.paid =0
)
union
(
SELECT company_id
FROM monthly_returns
WHERE monthly_returns NOT IN (SELECT * FROM paidreturns WHERE paidreturns.month = '$cdate'
)
) as x