I have a query like this:
SELECT DISTINCT(obt.oid) AS oid, o.borrower_email
FROM `order_borrower_tracker` obt
LEFT JOIN `orders` o ON obt.oid=o.oid
WHERE obt.date_acknowledged_edelivery = 0
AND 18 NOT IN
(SELECT DISTINCT(new_status) AS new_status
FROM `order_status_history`
WHERE oid=obt.oid)
Which works, but now I need to update this query so that not only "18" is not in the subselect, but also several other numbers.... something like
SELECT DISTINCT(obt.oid) AS oid, o.borrower_email
FROM `order_borrower_tracker` obt
LEFT JOIN `orders` o ON obt.oid=o.oid
WHERE obt.date_acknowledged_edelivery = 0
AND (18,27,29,41,53) NOT IN
(SELECT DISTINCT(new_status) AS new_status
FROM `order_status_history`
WHERE oid=obt.oid)
but obviously "(18,27,29,41,53) NOT IN" doesn't work.
What is a good alternative to achieve this? Without typing ANDs for each number
Use a trick with LEFT JOIN and IS NULL to find orders that don't have any records with listed statuses:
SELECT DISTINCT(obt.oid) AS oid, o.borrower_email
FROM `order_borrower_tracker` obt
LEFT JOIN `orders` o
ON obt.oid=o.oid
LEFT JOIN `order_status_history` h
ON h.oid=obt.oid AND h.new_status IN (18,27,29,41,53)
WHERE obt.date_acknowledged_edelivery = 0
AND h.oid IS NULL
Related
I have a table:
and this table:
I would like to create report like this
I've tried this SQL:
select
master_problem.problem,
master_problem.sop_reference,
master_problem.adidas_spec,
count(log_roving_qc.id_problem) as jumlahfrom
master_problem
inner join log_roving_qc
on master_problem.id_problem = log_roving_qc.id_problem
group by master_problem.id_problem
but the empty data does not show. I want to display blank data with a description of 0
Do a left join of the master_problem table to a subquery which does the count aggregation:
SELECT
mp.problem,
mp.sop_reference,
mp.adidas_spec,
COALESCE(t.cnt, 0) AS jumlahfrom
FROM master_problem mp
LEFT JOIN
(
SELECT id_problem, COUNT(*) as cnt
FROM log_roving_qc
GROUP BY id_problem
) t
ON mp.id_problem = t.id_problem;
I'm having a hard time wrapping my head around how the column product_count works. It seems to be somehow referencing itself with aliases see and e, which are both pointing to catalog_category_entity. Specifically,
WHERE (see.entity_id = e.entity_id) OR (see.path LIKE CONCAT(e.path, '/%'))
Both see and e are aliases for table catalog_category_entity. What is this doing?
Here's the entire query:
SELECT `e`.*, `d_name`.`value` AS `name`, IF(s_name.value_id > 0, s_name.value, d_name.value) AS `name`, `d_is_active`.`value` AS `is_active`, IF(s_is_active.value_id > 0, s_is_active.value, d_is_active.value) AS `is_active`, `d_is_anchor`.`value` AS `is_anchor`, IF(s_is_anchor.value_id > 0, s_is_anchor.value, d_is_anchor.value) AS `is_anchor`,
(
SELECT COUNT(DISTINCT scp.product_id)
FROM `catalog_category_entity` AS `see`
LEFT JOIN `catalog_category_product` AS `scp`
ON see.entity_id=scp.category_id
WHERE (see.entity_id = e.entity_id) OR (see.path LIKE CONCAT(e.path, '/%'))
) AS `product_count`,
(
SELECT COUNT(cp.product_id)
FROM `catalog_category_product` AS `cp`
WHERE (cp.category_id = e.entity_id)
) AS `self_product_count`
FROM `catalog_category_entity` AS `e`
LEFT JOIN `catalog_category_entity_varchar` AS `d_name` ON d_name.entity_id=e.entity_id AND d_name.attribute_id=41 AND d_name.entity_type_id=e.entity_type_id AND d_name.store_id=0
LEFT JOIN `catalog_category_entity_varchar` AS `s_name` ON s_name.entity_id=e.entity_id AND s_name.attribute_id=41 AND s_name.entity_type_id=e.entity_type_id AND s_name.store_id=0
LEFT JOIN `catalog_category_entity_int` AS `d_is_active` ON d_is_active.entity_id=e.entity_id AND d_is_active.attribute_id=42 AND d_is_active.entity_type_id=e.entity_type_id AND d_is_active.store_id=0
LEFT JOIN `catalog_category_entity_int` AS `s_is_active` ON s_is_active.entity_id=e.entity_id AND s_is_active.attribute_id=42 AND s_is_active.entity_type_id=e.entity_type_id AND s_is_active.store_id=0
LEFT JOIN `catalog_category_entity_int` AS `d_is_anchor` ON d_is_anchor.entity_id=e.entity_id AND d_is_anchor.attribute_id=51 AND d_is_anchor.entity_type_id=e.entity_type_id AND d_is_anchor.store_id=0
LEFT JOIN `catalog_category_entity_int` AS `s_is_anchor` ON s_is_anchor.entity_id=e.entity_id AND s_is_anchor.attribute_id=51 AND s_is_anchor.entity_type_id=e.entity_type_id AND s_is_anchor.store_id=0
WHERE (`e`.`entity_type_id` = '3') AND (e.entity_id IN('24', '533')) ORDER BY LENGTH(e.path) ASC
This is an example of a correlated query, here the query owner is checking a condition from outside of the sub-query with an OR clause.
In the below sub-query there is a distinct count of production_id which should exist in both tables: catalog_category_entity and catalog_category_product (even here there is no requirement of left join and an inner join may work better as you get count from the right side table) with condition that either entitiy_id should exist in catalog_category_entity as main table OR sub-query path field should match with the main table left part of path field means the main table may contain an extra string in right side but the left part should be same.
SELECT COUNT(DISTINCT scp.product_id)
FROM `catalog_category_entity` AS `see`
LEFT JOIN `catalog_category_product` AS `scp`
ON see.entity_id=scp.category_id
WHERE (see.entity_id = e.entity_id)
OR (see.path LIKE CONCAT(e.path, '/%'))
You can simplify your query if the requirement is clear as you are joining table catalog_category_entity_int 4 times with left join, while you can use as below only a single time:
LEFT JOIN catalog_category_entity_int` AS `d_is_anchor`
ON d_is_anchor.entity_id=e.entity_id
AND d_is_anchor.attribute_id IN (42,51)
AND d_is_anchor.entity_type_id=e.entity_type_id
AND d_is_anchor.store_id=0
I'm trying to make a count within several table with JOIN, but when I made several JOINs the COUNTs got wrongly counted.
Basically I've got 4 tables, named:
predective_search
predective_to_product
predective_to_category
predective_to_manufacturer
I want to count the total number of products, categories and manufacturer which has same id in table predective_search.
Here's my code:
SELECT * ,
COUNT(pp.predictive_id) AS total_products,
COUNT(pc.predictive_id) AS total_categories,
COUNT(pm.predictive_id) AS total_manufacturers
FROM predictive_search ps
LEFT JOIN predictive_to_product pp ON (ps.predictive_id = pp.predictive_id)
LEFT JOIN predictive_to_category pu ON (ps.predictive_id = pc.predictive_id)
LEFT JOIN oc_predictive_to_manufacturer pm ON (ps.predictive_id = pm.predictive_id)
GROUP BY ps.predictive_id
Also the GROUP BY is needed I think. I'm stuck at this as I'm not getting any way to do this
SELECT
ps.*,
agg_pp.total_products,
agg_pc.total_categories,
agg_pm.total_manufacturers
FROM predictive_search ps
LEFT JOIN (
SELECT pp.predictive_id, COUNT(*) AS total_products
FROM predictive_to_product pp
GROUP BY pp.predictive_id
) agg_pp ON ps.predictive_id = agg_pp.predictive_id
LEFT JOIN (
SELECT pc.predictive_id, COUNT(*) AS total_categories
FROM predictive_to_category pc
GROUP BY pc.predictive_id
) agg_pc ON ps.predictive_id = agg_pc.predictive_id
LEFT JOIN (
SELECT pm.predictive_id, COUNT(*) AS total_manufacturers
FROM predictive_to_category pm
GROUP BY pm.predictive_id
) agg_pm ON ps.predictive_id = agg_pm.predictive_id
Im trying to make some queries, first, I do this one (and works):
SELECT RP.id, RP.product_name, RP.price, RP.retailer_id, RP.product_id,
count(G.id) AS duration, G.active, RP.retprod_id, P.pr_id AS video
FROM retailer_products AS RP
LEFT JOIN groups G ON RP.id=G.retailer_product_id
INNER JOIN products P ON P.id=RP.product_id
WHERE (RP.product_id IN (1))
GROUP BY RP.id;
But when I do this one, it gaves me an empty set, the difference is that it has a "HAVING" at the end of the query over a field that may be: 0, 1 or NULL (because of the LEFT JOIN, I have no groups linked to the table retailer_product)
SELECT RP.id, RP.product_name, RP.price, RP.retailer_id, RP.product_id,
count(G.id) AS duration, G.active, RP.retprod_id, P.pr_id AS video
FROM retailer_products AS RP
LEFT JOIN groups G ON RP.id=G.retailer_product_id
INNER JOIN products P ON P.id=RP.product_id
WHERE (RP.product_id IN (1))
GROUP BY RP.id HAVING G.active=1;
So, I tried the following ways but no one works:
-- HAVING G.active=1
-- HAVING G.active=1 OR G.active=NULL
-- HAVING G.active0
What is the right way to handle this on MySQL? Thanks in advance!
The proper way to compare value with NULL is IS NULL. So you need to add HAVING G.active IS NULL OR G.active=1. Your code G.active=NULL is always NULL (false):
1 = NULL // NULL - false in conditions
NULL = NULL // NULL - false in conditions
NULL IS NULL // TRUE
Why you don't add the HAVING condition on the "Group" ON condition?
SELECT RP.id, RP.product_name, RP.price, RP.retailer_id, RP.product_id,
count(G.id) AS duration, G.active, RP.retprod_id, P.pr_id AS video
FROM retailer_products AS RP
LEFT JOIN groups G ON RP.id=G.retailer_product_id AND G.active=1
INNER JOIN products P ON P.id=RP.product_id
WHERE (RP.product_id IN (1))
GROUP BY RP.id;
I have a Microsoft SQL Server 2008 query that returns data from three tables using a left outer join. Many times, there is no data in the second and third tables and so I get a null which I think is the default for left outer join. Is there a way to replace the default values in the select statement? I have a workaround in that I can select into a table variable but it feels a little dirty.
SELECT iar.Description, iai.Quantity, iai.Quantity * rpl.RegularPrice as 'Retail',
iar.Compliance FROM InventoryAdjustmentReason iar
LEFT OUTER JOIN InventoryAdjustmentItem iai on (iar.Id = iai.InventoryAdjustmentReasonId)
LEFT OUTER JOIN Item i on (i.Id = iai.ItemId)
LEFT OUTER JOIN ReportPriceLookup rpl on (rpl.SkuNumber = i.SkuNo)
WHERE iar.StoreUse = 'yes'
I would like the Quantity and RegularPrice to default to zero if possible.
That's as easy as
IsNull(FieldName, 0)
Or more completely:
SELECT iar.Description,
ISNULL(iai.Quantity,0) as Quantity,
ISNULL(iai.Quantity * rpl.RegularPrice,0) as 'Retail',
iar.Compliance
FROM InventoryAdjustmentReason iar
LEFT OUTER JOIN InventoryAdjustmentItem iai on (iar.Id = iai.InventoryAdjustmentReasonId)
LEFT OUTER JOIN Item i on (i.Id = iai.ItemId)
LEFT OUTER JOIN ReportPriceLookup rpl on (rpl.SkuNumber = i.SkuNo)
WHERE iar.StoreUse = 'yes'
In case of MySQL or SQLite the correct keyword is IFNULL (not ISNULL).
SELECT iar.Description,
IFNULL(iai.Quantity,0) as Quantity,
IFNULL(iai.Quantity * rpl.RegularPrice,0) as 'Retail',
iar.Compliance
FROM InventoryAdjustmentReason iar
LEFT OUTER JOIN InventoryAdjustmentItem iai on (iar.Id = iai.InventoryAdjustmentReasonId)
LEFT OUTER JOIN Item i on (i.Id = iai.ItemId)
LEFT OUTER JOIN ReportPriceLookup rpl on (rpl.SkuNumber = i.SkuNo)
WHERE iar.StoreUse = 'yes'
MySQL
COALESCE(field, 'default')
For example:
SELECT
t.id,
COALESCE(d.field, 'default')
FROM
test t
LEFT JOIN
detail d ON t.id = d.item
Also, you can use multiple columns to check their NULL by COALESCE function.
For example:
mysql> SELECT COALESCE(NULL, 1, NULL);
-> 1
mysql> SELECT COALESCE(0, 1, NULL);
-> 0
mysql> SELECT COALESCE(NULL, NULL, NULL);
-> NULL
For Oracle you can use:
NVL(columnName,deafultValue) :- NVL is used to convert a null value to a default value in the query output. eg. If you want to replace null values with 'NA' then use something like this.
SELECT NVL(columnName,'NA') FROM tableName