Writing complex SQL query with 4 tables - php

I have 4 tables from which i want to output information with a single query and i'm not sure how to do that.
• From table1 i want to get all the records
• For each record from table1 i want to take out the SUM from field1 from all records in table2 on a matching id taken from table1
• For each record from table1 i want to take out the SUM from field1 from all records in table3 on a matching id taken from table1
• For each record from table1 i want to take out the value of a single record from table4 on a matching id taken from table1
EDIT:
Here is how i think the graphic for my request should look:
Here's my working code:
SELECT DISTINCT
i.id,
i.dateCreated,
i.dateBilled,
i.dateCompleted,
i.userId,
i.type,
i.status,
i.truck,
i.poNumber,
i.total,
i.billtoId,
i.shiptoId,
i.invoiceNumber,
i.loadNumber,
SUM(p.amount) as amountpaid,
c.name as billtoName
FROM `invoices` as i
LEFT JOIN `invoice_payments` as p ON i.id = p.invoice
RIGHT JOIN `companies` as c ON c.id = i.billtoId
GROUP BY i.id, i.invoiceNumber
You can see how i managed to get the SUM from all payments on my invoices with a left join. I'm trying to do the same for i.total, but as soon as i add another LEFT JOIN my calculations come up wrong and the result in amountpaid doubles

You can write this query with subqueries in the SELECT statement:
SELECT id,
(SELECT sum(field1) FROM t2 WHERE t2.idfrom1=t1.id) AS firstSum,
(SELECT sum(field1) FROM t3 WHERE t3.idfrom1=t1.id) AS secondSum,
(SELECT min(field1) FROM t4 WHERE t4.id=t1.f2 LIMIT 1) AS singleRecord
FROM t1
This is the idea, you just have to adapt it to your schema.
edit: updated from the drawing

Related

How to Avoid SubQuery with same output in MySql

Good Day!
I already saw other post about avoiding subquery / using JOIN statement, but still I can't figure it out why my query is so very slow to execute the 9 result data. but when the result data is more than thousands the query execute 0.7k ms only.
My question is , how can I speed up this query execution, what will I remove/add, Or do I need to re-construct the query? how?
here's my query
SELECT a.ts, b.bc, b.rem, c.dept FROM table1 a
INNER JOIN (select doc, max(ID) from table1 Group By doc) d ON d.doc=a.doc AND d.ID=a.ID
INNER JOIN table2 c ON c.u_id=a.u_id
INNER JOIN table3 b ON b.id=a.doc
WHERE c.depart = 'deparment' AND b.end = 0
here is the Screen Shot of
EXPLAIN result
Updated SS for EXPLAIN result
I already set INDEX :
ALTER TABLE table3 ADD INDEX max_id (end,id,bc);
ALTER TABLE table1 ADD INDEX max_id (ID,doc,u_id,ts,rem);
ALTER TABLE table1 ADD INDEX m_id (doc,ID);
ALTER TABLE table2 ADD INDEX user_max (dept,u_id);
Try a correlated subquery:
SELECT a.ts, b.bc, b.rem, c.dept
FROM table1 a INNER JOIN
table2 c
ON c.u_id = a.u_id INNER JOIN
table3 b
ON b.id =a.doc
WHERE c.depart = 'deparment' AND b.end = 0 AND
d.id = (SELECT MAX(t1.id) FROM table1 t1 WHERE t1.doc = a.doc);
For the correlated subquery you want an index on table1(doc, id).

How to obtain search query using join command in mysql

I have two table
Table 1:
Ensemble_ID
Target
Gene_length
miRNA
miRNA_length
mfe
pvalue
position
prediction
no_of_seeds
And in table2
Ensemble_ID
local_ID
I want to display the result in the following order,
Ensemble_ID, local_ID, Ensemble_ID, Target ,Gene_length, miRNA, miRNA_length, mfe, pvalue, position, prediction, no_of_seeds
But i could not join it .. Can some one help ??
This is what you are asking:
SELECT t1.Ensemble_ID AS Ensemble_ID1, t2.local_ID, t2.Ensemble_ID AS Ensemble_ID2,
t1.Target, t1.Gene_length, t1.miRNA,
t1.miRNA_length, t1.mfe, t1.pvalue, t1.position, t1.prediction, t1.no_of_seeds
FROM table1 t1, table2 t2
But it think you want something like this:
SELECT t2.local_ID, t2.Ensemble_ID, t1.Target, t1.Gene_length, t1.miRNA,
t1.miRNA_length, t1.mfe, t1.pvalue, t1.position, t1.prediction, t1.no_of_seeds
FROM table1 t1
INNER JOIN table2 t2 ON (t2.Ensemble_ID = t1.Ensemble_ID)
If you want to join table1 and table2 on Ensemble_ID there is no need to output it twice

How to Match last inserted single column against multiple values in child table using Join

I have one table jobs in my database. and its two child tables. one job_status_detail and job_assigned.
One job may have multiple status like created,started,completed in job_status_detail with one job_id.
One job can assigned to multiple user with job_id in job_assigned.
Now i want all job records with last inserted status in job_status_detail.
I use following query
SELECT * FROM `jobs` as `t`
LEFT OUTER JOIN `job_assigned` as `jobDetail` ON (`jobDetail`.`job_id`=`t`.`id`)
LEFT OUTER JOIN `job_status_detail` as `job` ON (`job`.`job_id`=`t`.`id`) WHERE jobDetail.assign_to=1
Order by job.id
but it gives me whole data. if one job has three entry in job_status_detail, it gives me 3 entries.Not last inserted entry.
Result should like one job with one job status(last inserted).
Here is my solution.
SELECT * FROM `jobs` as `t`
LEFT OUTER JOIN `job_assigned` `jobDetail` ON (`jobDetail`.`job_id`=`t`.`id`)
INNER JOIN (select max(id) id from `job_assigned` group by `job_id`) j ON jobDetail.id=j.id
LEFT OUTER JOIN `job_status_detail` `job` ON (`job`.`job_id`=`t`.`id`)
INNER JOIN (select max(id) id from job_status_detail group by job_id) jsd ON job.id=jsd.id
WHERE jobDetail.assign_to=1
You have to put group by tag
SELECT * FROM `jobs` as `t`
LEFT OUTER JOIN `job_assigned` as `jobDetail` ON (`jobDetail`.`job_id`=`t`.`id`)
LEFT OUTER JOIN `job_status_detail` as `job` ON (`job`.`job_id`=`t`.`id`)
GROUP BY job.job_status Order by job.id

MySQL RIGHT JOIN SUM() from Table B to Info on Table A

Basically I have a load of product information on Table A. This include the product_id which is the common id over both tables. On Table B I have a list of votes which include product_id, username, thevote(could be +1 or -1).
So basically I want to have a table of 'Table A' with a additional column containing the SUM of all the votes for that product_ID. I am sure there is an easy way to do this. Which i think is using 'right join'.
I still want it to list all the products in Table A regardless if they have a single +1 or -1 vote.
Many thanks in advance peoples!
You could use group by statement and left join like:
select productName, sum(vote) as productVoteSum
from `products` p
left join `products_votes` pv on p.id = pv.productId
where productName like '%chocolat%'
group by p.id
order by productName;
You can do a LEFT JOIN (that goes through all the information on tableA and puts the SUM in the ones that have the matching product_id on tableB), then you add the SUM(b.thevote) and group by the remaining columns
SELECT a.product_id,a.productName,SUM(b.thevote)
FROM tableA a
LEFT JOIN tableB b ON a.product_id = b.product_id
GROUP BY a.product_id, a.productName
SELECT a.*, SUM(b.votes) FROM TableA a LEFT JOIN TableB b ON a.prouct_id=b.product_id
GROUP BY a.product_id

Select unmatched records from two tables of MYSQL

I have two tables Table1 and Table2 with some records
id is the common column in both tables and primarykey is set to this column in table1
There are many records in table1 and some of these records (not all) are updated into table2.
Now I want retrieve from table1 the records not updated into the table2.
For example in table1 there are records 1,2,3,4,5,6,7,8,9
And in table2 there are 3,4,7,9
Now How can I retrieve these records form table1 1,2,5,6 those not updated into table2
I wrote this query :
SELECT Table1.id, Table1.DATE, Table1.C_NAME, Table1.B_NAME
FROM [Table1] INNER JOIN Table2 ON Table1.SLIPNO <>Table2.id;
But the expected result not coming. This query lists all the records repeating each one record manytimes
Can any body give me solution to get the expected result.
select *
from table1
where table1.slip_no NOT IN (select id from table2)
Assuming name of common column is id
Or you can modify your query as
SELECT distinct (Table1.id, Table1.DATE, Table1.C_NAME, Table1.B_NAME)
FROM [Table1]
INNER JOIN Table2 ON Table1.SLIPNO <>Table2.id
A good reference on SQL joins
SELECT t1.*
FROM table1 AS t1
LEFT OUTER JOIN table2 AS t2 USING(id)
WHERE
t2.id IS NULL;
You can use the NOT IN operator on a subquery for table2.
Alternatively, use MINUS with two regular queries listing the ids in each table:
SELECT id FROM table1
MINUS
SELECT id FROM table2;
Try this
SELECT Table1.id, Table1.DATE, Table1.C_NAME, Table1.B_NAME FROM [Table1]
WHERE
NOT EXISTS (SELECT * from Table2 WHERE Table1.SLIPNO !=Table2.id );
You can use the following query
SELECT id FROM database1.table WHERE id NOT IN(SELECT id FROM database2.table)
SELECT child_table.id FROM child_table LEFT JOIN parent_table ON child_table.parent_id = parent_table.id WHERE parent_table.id IS NULL
This left join query returns all the records of the child_table when there is no match in the parent_table. When there is no match, all parent_table fields will be NULL.
inner join will not help. To get unmatched records I tried this:
SELECT
A.ID,A.DATE,A.NAME
FROM TABLE1 A
WHERE CONCAT(A.ID , A.DATE ,A.NAME)
NOT IN
(SELECT CONCAT(B.ID , B.DATE ,B.NAME) as X
from TABLE2 B) ;

Categories