I have three tables, inventory_location, item, item_stock
inventory_location :
inv_loc_id (PK)
inv_loc_desc
item :
item_id (PK)
code_no
item_desc
inv_cat_id
item_stock :
item_stock_id (PK)
item_id
inv_loc_id
quantity
I want to display a report like this :
Code Description Loc1 Loc2 Total
1 Desc1 5 3 8
inventory_location has data : (Loc1,Loc2,Loc3,Loc4,Loc5) & can be added with another record.
My problem is, if a location is not yet in item_stock - meaning no item stored in it yet, it will display like the following :
Code Description Loc1 Loc2 null null Total
1 Desc1 5 3 0 0 8
What I need is, to display all the locations even if they are not yet in item_stock.
Here's my query, hopefully you could correct me.
SELECT
il.`inv_loc_id` AS inv_loc_id,
il.`inv_loc_desc` AS inv_loc_desc,
i.`item_id` AS item_id,
i.`nrc_no` AS nrc_no,
i.`code_no` AS code_no,
i.`item_desc` AS item_desc,
i.`unit_id` AS unit_id,
iss.`item_stock_id` AS item_stock_id,
iss.`inv_loc_id` AS inv_loc_id,
iss.`quantity` AS quantity,
i.`inv_cat_id` AS inv_cat_id
FROM `item` i
LEFT JOIN `item_stock` iss
ON iss.`item_id` = i.`item_id`
LEFT JOIN `inventory_location` AS il
ON il.`inv_loc_id` = iss.`inv_loc_id`
WHERE i.inv_cat_id = 1
GROUP BY iss.inv_loc_id,
i.item_id
ORDER BY iss.item_stock_id DESC
FROM inventory_location il
LEFT JOIN item_stock iss ON iss.inv_loc_id = il.inv_loc_id
LEFT JOIN item i ON iss.item_id = i.item_id
Change your FROM clause so that you start with inventory_location.
Related
In sql help i have 3 tables, table one is asset table which is as follow
id
asset_code
asset_name
asset_group
asset_quantity
1
A001
computer
4
7
2
A002
keyboard
6
4
and another table is asset_allocation
id
asset_id
allocated_quantity
allocated_location
returned
1
1
2
IT office
no
2
2
1
main hall
yes
the last table is asset_liquidated which will present assets that are no longer going to be used
id
asset_id
liquidated_quantity
1
1
1
Now lets say that i have 7 computer out of which 2 are allocated but not returned and i have 4 keyboards out of which 1 is allocated and it is returned back and 1 computer is liquidated means it is never going to be used
so now here i want to join these 3 tables and find inventory of my current stock in hand.
Now this is the query now i need to add this
where asset_allocation.returned is enum no inside this query
SELECT id,asset_code, asset_name, asset_group, asset_quantity,allocated_quantity,liquidated_quantity,
asset_quantity - COALESCE(AA.allocated_quantity, 0) - COALESCE(AL.liquidated_quantity, 0) available_quantity
FROM asset A
LEFT JOIN (SELECT asset_id, SUM(allocated_quantity) allocated_quantity
FROM asset_allocation
GROUP BY asset_id) AA ON A.id = AA.asset_id
LEFT JOIN (SELECT asset_id, SUM(liquidated_quantity) liquidated_quantity
FROM asset_liquidated
GROUP BY asset_id) AL ON A.id = AL.asset_id;
I believe what you are looking for is adding WHERE returned = 'no' in your first JOIN like so:
SELECT id,asset_code, asset_name, asset_group, asset_quantity,allocated_quantity,liquidated_quantity,
asset_quantity - COALESCE(AA.allocated_quantity, 0) - COALESCE(AL.liquidated_quantity, 0) available_quantity
FROM asset A
LEFT JOIN (SELECT asset_id, SUM(allocated_quantity) allocated_quantity
FROM asset_allocation
WHERE returned = 'no'
GROUP BY asset_id) AA ON A.id = AA.asset_id
LEFT JOIN (SELECT asset_id, SUM(liquidated_quantity) liquidated_quantity
FROM asset_liquidated
GROUP BY asset_id) AL ON A.id = AL.asset_id;
That changes the available quantity for keyboard from 3 to 4 for me
your query:
vs. mine:
I have tblOuts that tracks Skus out of inventory by Category and date:
OutDate
Category
Sku
20210322
A
111
20210322
B
222
20210323
A
111
20210323
B
222
20210323
B
333
20210324
D
444
I created a crosstab that will show the count of Skus by Category and OutDate:
Category
20210322
20210323
20210324
A
1
1
B
1
2
D
1
How can I modify the crosstab to also show Category C, even though it doesn't have any data in my table yet?
Category
20210322
20210323
20210324
A
1
1
B
1
2
C
D
1
Normally I would create a separate table that listed all Categories and left join it to the crosstab. But I can't think of an ideal way to do so.
SELECT tblCategories.Category, qryCrosstab.*
FROM tblCategories LEFT JOIN qryCrosstab ON tblCategories.Category = qryCrosstab.Category
gives me two Category fields, which I don't want:
tblCategories.Category
qryCrosstab.Category
20210322
20210323
20210324
Alternately, I could do the following, but would need to modify my query every time a new date is added to the table:
SELECT tblCategories.Category, qryCrosstab.20210322, qryCrosstab.20210323, qryCrosstab.20210324
FROM tblCategories LEFT JOIN qryCrosstab ON tblCategories.Category = qryCrosstab.Category
Yes, I see what you mean by "doubled":
SELECT
Category.Category,
qOut.*
FROM
Category
LEFT JOIN
qOut ON Category.Category = qOut.Category;
Can't you just ignore one of those category fields?
I have a main table called "product" that is linked with three tables:
"product_type",
"feature",
"type_feature"
and a cross table called "product_feature" that contains several features of the same product.
Example one record:
I have something similar like this:
product_type
id_product_type name
1 Phone
feature
id_feature name
1 Memory
2 Color
3 Memory Ram
feature_type
id_feature_type id_feature value
1 1 16GB
2 1 32GB
3 2 Blue
4 2 Black
5 3 2GB
6 3 3GB
product
id_product id_product_type price quantity model
1 1 100$ 5 Moto-G7
Cross table "product_feature" (linked to "product", "feature" and "feature_type"):
id_feature id_product id_feature_type
1 1 1
2 1 3
3 1 6
I want query show this:
id_product type_name price quantity model feature_name value
1 Phone 100$ 5 Moto-G7 Memory 16GB
feature_name2 value2 feature_name3 value3
Color Blue Memory Ram 3GB
I tried this, but only I have only one feature_name and value, and I need three:
SELECT p.id_product, pt.name, model, price, quantity, f.name AS feature, ft.value
FROM product p
LEFT JOIN product_type pt ON pt.id_product_type = p.id_product_type
LEFT JOIN product_feature pf ON pf.id_product = p.id_product
LEFT JOIN feature f ON f.id_feature = pf.id_feature
LEFT JOIN feature_type ft ON ft.id_feature_type = pf.id_feature_type
GROUP BY p.id_product;
Try this query, It will give you the results:
SELECT product.*, product_type.name as TypeName, (SELECT CONCAT( GROUP_CONCAT(feature_type.value), "|", GROUP_CONCAT(feature.name) ) FROM `product_feature` INNER JOIN feature_type on product_feature.id_feature_type = feature_type.id_feature_type INNER JOIN feature on feature_type.id_feature = feature.id_feature WHERE product_feature.id_product=1 GROUP BY product_feature.id_product) as options FROM `product` LEFT JOIN product_type on product.id_product_type = product_type.id_product_type
You will get options for your product and you have to explode() those options by "|" and you can count how many options you have by using $count= count(explode("|", $options))
By this way you can get all options .
I'm setting up an "order management" application which should provide a datalist listing up all my catalog item and show for each of them the "last order date". I also want the items not ordered yet to be reflecting without last order date.
I have tried this query without success
SELECT i.id, i.name, d.name
FROM items i
JOIN LEFT orders o
ON i.id = o.items
I have these tables in my MySQL database:
ITEMS
ID|Name
-----------
0 |Table
1 |Chair
2 |Screen
3 |Speaker
4 |Keyboard
5 |Laptop
6 |Mug
ORDERS
ID|ITEMS|DATE
-----------------
0 | 0 |20190122
1 | 0 |20181231
2 | 1 |20180601
3 | 3 |20180122
4 | 2 |20171231
5 | 4 |20180501
4 | 6 |20171115
5 | 3 |20180101
And would like the following output :
LAST_ORDER_DATE
ID|NAME |DATE
--------------------
0 |Table |20190122
1 |Chair |20180601
2 |Screen |20171231
3 |Speaker |20180122
4 |Keyboard|20180501
5 |Laptop |
6 |Mug |20171115
Thanks for any help
seems you need max date so you could use max( ) function and group by
select i.id, i.name, max(o.date)
FROM items i
LEFT JOIN orders o ON i.id = o.items
group by i.id, i.name
you can also convert the existing string (if it is a char field) to date format like the following query if needed
select i.id, i.name, max(str_to_date(date,'%Y%m%d'))
FROM items i
LEFT JOIN orders o ON i.id = o.items
group by i.id, i.name
Try this :
change the table and column names as you have:
SELECT
t1.name,
MAX(t2.pdate) AS last_order_date
FROM
test t1
LEFT JOIN test1 t2 ON t1.id = t2.items
GROUP BY
t2.items,
t1.name
ORDER BY
last_order_date;
Tables :
Output :
if you are using string value in date then convert to date.
i have 3 tables. need to display records join results as well as remaing qty without join
tblBookhead
BookHeadId, bookname, bookauthor,...
tblBookDetail
BookHeaddetailId,BookHeadId,Qty
tblBookorder
orderid,BookHeaddetailId , orderqty
select * from tblBookhead bh inner join tblBookDetail bd on
bh.BookHeadId=bd.BookHeadId inner join tblBookorder br on
br.BookHeaddetailId=db.BookHeaddetailId where BookHeadId=1;
this will retrun good results no problem.
but now if qty is 10 for BookHeadId=1 and orderqty=5 then result need to display remaing 5 qty without join (my expectation is null values for remaining qty in tblBookorder )
my expected result would be:
BookHeadId, bookname, bookauthor,... BookHeaddetailId,BookHeadId,Qty,orderid,BookHeaddetailId , orderqty
1 1 john 1 1 10 1 1 5
1 1 john 1 1 10 null null null