data show from 4 table mysql - php

How to show the common data from all table on base of vendorID where vendorID is unique key in my vendor table. and i use this as an foriegn key for all other(cost table, hour table,employee table, temporary table and ) table.
This is my Cost table struructre
This is my Hour table structure
This is my Temporarytable structure
This is my Employee table
This is my Final table vendor there are vendorID is unique Key
And i have use the following query but it is showing the different data.
SELECT * FROM cw_employee_csv as emp
inner join cw_cost_hour as cost on cost.vendorid=emp.vendorid
inner join cw_temp_employee as temp on cost.vendorid=temp.vendorid
inner join cw_hour_company as hour on temp.vendorid=hour.vendorid
inner join cw_vendor as vendor on temp.vendorid=vendor.vendorid
where vendor.companyid=1 ORDER BY hour.timeFrom ASC

If I understand, try this:
In your query in the field list explicit fields you want to show, for example:
SELECT
emp.assignmentid, cost.bill_type
FROM
cw_employee_csv AS emp
INNER JOIN
cw_cost_hour AS cost ON cost.vendorid = emp.vendorid
INNER JOIN
cw_temp_employee AS temp ON cost.vendorid = temp.vendorid
INNER JOIN
cw_hour_company AS hour ON temp.vendorid = hour.vendorid
INNER JOIN
cw_vendor AS vendor ON temp.vendorid = vendor.vendorid
WHERE
vendor.companyid = 1
ORDER BY
hour.timeFrom ASC
If the cardinality of tables is different and you want to show only one row per vendor, you must write a main query with cw_vendor and use some subquery to retrieve additional information by other table. Obviously, about parent table of your vendor table you can use INNER JOIN information without use subqueries.
EDIT AFTER COMMENT:
You start by this query (after chat discussion):
I extract an aggregate by company (I suppose to summarize your cost by vendor, if you want to apply another formula, it's the same algorithm)
select
sum(t.vendor_cost), t.companyid
from
(select
vendor.companyid as companyid, vendor.id as vendorid,
(select SUM(c.cost)
from cw_cost_hoyr c
where c.vendorid = vendor.id) as vendor_cost
from
cw_vendor vendor) as t
group by
t.companyid
Now we add other information but I must understand what do you want exactly with their relations

Related

How to show one row if it has more rows in inner join and left join query?

I have more than one shop in ps_shop table and its some of shop have in ps_storeinfo table but those shop of ps_shop table are not in ps_storeinfo table that are needed to insert into ps_storeinfo with user id and shop name. Here shopname of ps_shop table = storename in ps_storeinfo table. Here I have written sql query for this and I am getting all data but problem is more than one user is coming by my SQL if it have more than one user. I need one user for one shop.
In ps_ employee_shop table user is assigned for shop base on shop id. And In ps_ employee table is for user. This is for prestashop 1.6.
My SQL is given below :
$table_prefix = _DB_PREFIX_;
'SELECT ps.*, pe.email, pe.firstname, pe.lastname, pes.id_employee,psi.storename
FROM '.$table_prefix.'shop ps
LEFT JOIN '.$table_prefix.'storeinfo psi ON ps.name = psi.storename
INNER JOIN '.$table_prefix.'employee_shop pes ON ps.id_shop = pes.id_shop
INNER JOIN '.$table_prefix.'employee pe ON pes.id_employee = pe.id_employee where ps.id_shop <>1 and pe.id_employee <>1
GROUP BY pes.id_employee
';
Output image is:
Well, if more than one entity exists in the table on the right side of the JOIN with the matching ON key any relational DB engine will return one row for each matching entity on the right side, duplicating the left side of the JOIN clause.
In the scenario described you need to decide which user you want to return. The first one sorted alphabetically? The one created most recently?
Based on the answer you will need to use a JOIN with a correlated subquery. Here's an example for getting the employee with the highest value of id_employee:
SELECT
ps.*, pe.email, pe.firstname, pe.lastname, pes.id_employee,psi.storename
FROM
'.$table_prefix.'shop ps
LEFT JOIN '.$table_prefix.'storeinfo psi ON ps.name = psi.storename
INNER JOIN (
SELECT
pe.email, pe.firstname, pe.lastname, pes.id_employee
FROM
'.$table_prefix.'employee pe
'.$table_prefix.'employee_shop pes ON pes.id_employee = pe.id_employee
WHERE
pe.id_employee <> 1
AND ps.id_shop = pes.id_shop
ORDER BY
pe.id_employee DESC
LIMIT 1
)
WHERE
ps.id_shop <>1
As you can see what this is really doing is limiting the resulting list of employees to just one record to avoid duplication. In this case the list is ordered by id_employee, but the correct ordering depends on the business logic that needs to be implemented.

How to sum values across a set of categories, in SQL?

I want to get a list of category items and display the total amount linked to those categories. I have the "amount" field in the "transaction" table and I want to link it to category table.
This is how my tables are:
Category Master
Subcategory Master
Item Master
Transaction
So to get my "Amount" field to category, I would have to pass a certain common column between them. I have CategoryID in SubCategory master, subcatid in item master and similarly itemid in transaction.
Earlier when I grouped the amount using transaction date, the process went smoothly:
SELECT TransactionDate, SUM(Amount) FROM transaction GROUP BY MONTH(TransactionDate)
Now the problem I'm facing with grouping it using categoryname is that all of the amount seems to be =50 whereas it is still different in the database. I know that this is something really silly, but I am comparatively new to programming and not sure how to use logic appropriately.
SELECT categorymaster.CategoryName, transaction.Amount
FROM categorymaster
INNER JOIN subcategorymaster
INNER JOIN itemmaster
INNER JOIN transaction
GROUP BY categorymaster.CategoryName
This answer assumes your primary key in each table is named "ID". You didn't provide that info.
SELECT categorymaster.CategoryName, sum(transaction.Amount)
FROM categorymaster
INNER JOIN subcategorymaster
ON subcagetorymaster.CategoryId = categorymaster.ID
INNER JOIN itemmaster
ON itemmaster.SubCatId = subcategorymaster.ID
INNER JOIN transaction
ON transaction.ItemId = itemmaster.ID
GROUP BY categorymaster.CategoryName

Make a table from from table A and table B where match

MySQL noob here. I need to create a product catalog table from two others. Table A has a product weight and Table B has description. So I need to make a Table C with the weight and description of course.
These catalogs are different, from different sources, and the only field I can match is SKU.
Should I make Table C from a copy of Table A (with weight), then add a description column, then:
update tableC
join tableA on tableB.sku = tableA.sku
set description = tableB.description
Creating another table to copy and hold values related to each other from two other tables is a poor approach. SQL is a relational language; you should leverage that to simply get both values from both tables:
SELECT
tableA.weight
, tableB.description
FROM tableA
LEFT JOIN tableB on tableB.sku = tableA.sku
No need to create a copy to relate the two in a whole other table. That's unnecessary complexity.
Maybe
INSERT INTO
TableC (`weight`,`desc`)
SELECT
TableA.weight, TableB.desc
FROM
TableA
INNER JOIN
TableB ON TableA.id = TableB.id;
?
(see http://dev.mysql.com/doc/refman/5.0/en/insert-select.html)

How to copy data from one table to another in MySQL?

What I'm trying to do should be really simple. I have two tables with the following columns:
Table 1:
Name, Level
Table 2:
Name, Cost
Name is the primary key. I want to combine both table's data into one table that has all three columns. What I've been trying to do is add a Cost column into Table 1 and copy all the Cost values from Table 2 into it. I've tried numerous suggestions from other threads on this site and I've never had one work for me. The new Cost column in Table 1 never budged with any new values. Why?
I am doing this on MySQL Workbench on Ubuntu.
Here's one that I tried using (New cost column already made for Tbl1):
UPDATE Tbl1
SET Cost = (
SELECT Cost
FROM Tbl2
WHERE Name = 'SpecificName')
WHERE Name = 'SpecificName;
This works when I specify individual rows but it doesn't work when I replace Name = 'SpecificName' with something like "Tbl1.Name = Tbl2.Name"
The problem you face is when some names are in one table but not the other. Here is one method, using a single create table as:
create table NameLevelCost as
select n.name, t1.level, t2.cost
from (select name from table1
union
select name from table2
) n left join
table1 t1
on t1.name = n.name left join
table2 t2
on t2.name = n.name;
This assumes that name is unique in each of the tables.
update Tbl1 t1 left join Tbl2 t2 on t2.Name = t1.Name set t1.Cost = t2.Cost;

Using multiple inner joins

I have four tables:
users, orders, orders_product and products.
They are connected to each other by foreign key
user tables contains: id, name, email and username.
product table contains: id, product_name, product_description and product_price
orders table contains: id, u_id(foreign key).
orders_product table contains: id, product_id(foreign key), order_id(foreign key).
Now I was trying to fetch the name of a user with the total price of a particular order that he has placed.
The maximum I could went for was something like this:
SELECT prod.order_id,
SUM(product_price) AS Total
FROM products
INNER JOIN
(SELECT orders.id AS order_id,
orders_product.product_id
FROM orders
INNER JOIN orders_product ON orders.id = orders_product.order_id
WHERE order_id=1) AS prod ON products.id = prod.product_id;
It showed me total price of a particular order. Now I have two questions:
Is that query correct. It looks like a very long query. Can the same result be achieved with a smaller one?
How to fetch the name of a user with the total price of a particular order that he has placed.
Hi some addition to #Gordon Linoff
your query seems ok.
if you store your price data in order_products it will be good and some benefit, one of these benefit is aggregation will be simple. Second benefit if product price change it will not affect to order.
Your query is correct for one order, but it can be improved:
Don't use a subquery unless necessary. In MySQL this introduces additional overhead.
You are only looking at one order, which seems on the light site. You should remove the where clause.
You should be using a group by because you want aggregation.
You need to join in the user table to get the name.
I also added table aliases (abbreviations for table names). This makes the query a bit more readable:
SELECT u.name, SUM(p.product_price) as Total
FROM orders_product op INNER JOIN
orders o
ON o.id = op.order_id INNER JOIN
products p
ON p.id = op.product_id INNER JOIN
users u
on o.userid = u.id
WHERE op.order_id = 1
GROUP BY u.name;
Your SQL is wrong. Because You want to calculate specific to user. But your SQL is specific to Order. Your SQL will give result for One Order. Please make it User Specific by giving user name or what ever is unique.

Categories