I am having trouble joining mutiple tables.
I can get 2 to join, but I get an error when I try to join all three:
This works:
SELECT `capman`.`cman_code`, `capman`.`cman_name`, `caprange`.`cran_name`, `caprange`.`cran_mantextcode`
from capman, caprange
LEFT JOIN `capder` ON `caprange`.`cran_code` = `capder`.`cder_rancode`
AND `capder`.`cder_discontinued` = '0000-00-00 00:00:00'
LIMIT 10
And this works:
SELECT `capman`.`cman_code`, `capman`.`cman_name`, `caprange`.`cran_name`, `caprange`.`cran_mantextcode`
from capman
LEFT JOIN `caprange` ON `caprange`.`cran_mantextcode` = `capman`.`cman_code` WHERE LCASE(cman_name) IN ('arbarth','alfa romeo','aston')
LIMIT 10
But when I try to put them together like this:
SELECT `capman`.`cman_code`, `capman`.`cman_name`, `caprange`.`cran_name`, `caprange`.`cran_mantextcode`
from capman, caprange
LEFT JOIN `caprange` ON `caprange`.`cran_mantextcode` = `capman`.`cman_code` WHERE LCASE(cman_name) IN ('arbarth','alfa romeo','aston')
LEFT JOIN `capder` ON `caprange`.`cran_code` = `capder`.`cder_rancode` AND `capder`.`cder_discontinued` = '0000-00-00 00:00:00'
LIMIT 10
I get the error:
Not unique table/alias: 'caprange'
Not sure if you mean to join caprange twice. If so, you can use alias to point to the right table. The query could be rewritten as:
SELECT `capman`.`cman_code`, `capman`.`cman_name`, `caprange`.`cran_name`, `caprange`.`cran_mantextcode`
from capman, caprange r1
LEFT JOIN `caprange` r2 ON r2.`cran_mantextcode` = `capman`.`cman_code` WHERE LCASE(cman_name) IN ('arbarth','alfa romeo','aston')
LEFT JOIN `capder` ON r1.`cran_code` = `capder`.`cder_rancode` AND `capder`.`cder_discontinued` = '0000-00-00 00:00:00'
LIMIT 10
Since I am not sure which table you are joining with caprange, replace r1/r2 in the query with the right alias.
Related
How can I access data from an outer table in a SELECT, and use it in an WHERE inside a JOIN estructure?
Below is the current query:
SELECT
cvl.id caracteristica_valor_id,
cvl.nome caracteristica_valor_nome,
cvl.valor caracteristica_valor_valor,
ctp.id caracteristica_tipo_id,
ctp.nome caracteristica_tipo_nome,
ctp.codigo caracteristica_tipo_codigo,
ctp.tipo caracteristica_tipo_tipo,
COUNT(DISTINCT var.id_perfil_produto) quantidade_itens
FROM
caracteristica_variacao cvr
INNER JOIN caracteristica_valor cvl ON cvl.id = cvr.id_caracteristica_valor
INNER JOIN caracteristica_tipo ctp ON ctp.id = cvl.id_caracteristica_tipo
INNER JOIN variacao var ON var.id = cvr.id_variacao
INNER JOIN(
SELECT DISTINCT
ppr.id perfil_produto_id
FROM
perfil_produto ppr
INNER JOIN produto pro ON pro.id = ppr.id_produto
INNER JOIN(
SELECT ppr2.id AS id_perfil_sub,a
COUNT(var.id) AS qtd_variacoes,
SUM(var.quantidade_estoque) AS quantidade_estoque,
COALESCE(SUM(var.quantidade_estoque_reservada),0) AS quantidade_estoque_reservada,
MIN(var.disponibilidade) AS disponibilidade,
MIN(var.frete_gratis) AS frete_gratis,
MIN(var.preco_venda) AS preco_venda,
MAX(var.preco_listagem) AS preco_listagem
FROM
variacao var
LEFT JOIN perfil_produto ppr2 ON ppr2.id = var.id_perfil_produto
LEFT JOIN caracteristica_variacao cvr_1 ON cvr_1.id_variacao = var.id
LEFT JOIN caracteristica_valor cvl_1 ON cvl_1.id = cvr_1.id_caracteristica_valor
LEFT JOIN caracteristica_tipo ctp_1 ON ctp_1.id = cvl_1.id_caracteristica_tipo
WHERE
var.disponibilidade = 1
AND(
ctp_1.codigo = 'tamanho' AND cvl_1.valor IN('p')
)
GROUP BY
ppr2.id
) AS grp_var ON grp_var.id_perfil_sub = ppr.id
INNER JOIN produto_categoria prc ON pro.id = prc.produto_id
INNER JOIN categoria cat ON prc.categoria_id = cat.id
WHERE
pro.disponibilidade = 1 AND prc.categoria_id IN (164, 165, 166)
) AS produto ON produto.perfil_produto_id = var.id_perfil_produto
GROUP BY
cvl.id
ORDER BY
ctp.tipo ASC,
ctp.id
I need the field ctp.codigo from the outer table inside thist part:
WHERE
var.disponibilidade = 1
AND(
ctp_1.codigo = 'tamanho' AND cvl_1.valor IN('p')
)
for this section to be as follows:
WHERE
var.disponibilidade = 1
AND(
(ctp.codigo != 'tamanho' AND ctp_1.codigo = 'tamanho' AND cvl_1.valor IN('p'))
OR
(ctp.codigo = 'tamanho')
)
It's not possible to reference columns from the outer query from inside an inline view query.
In the MySQL venacular, the inline view query is called a "derived table". And that name makes sense, because of the way MySQL processes it. The execution plan first materializes the inline view query into a temporary(-ish) table. Once that is done, then the outer query can run, referencing the contents of the derived table.
MySQL doesn't have available the columns from the outer query at the time the inline view query runs.
It is possible to reference columns from the outer query inside a subquery that appears for example in the SELECT list, or in the WHERE clause. We call a subquery that references columns from outer query a "correlated subquery".
Is there any workaround to get unique rows which are in zc_orders table? I only need comments field from zc_zc_orders_status_history (which have duplicate rows). This is my query:
SELECT
zc_orders.orders_id,
zc_orders_status_history.comments,
zc_orders_status_history.orders_status_id,
zc_customers.customers_email_address,
zc_customers.customers_telephone,
zc_customers.customers_firstname,
zc_customers.customers_lastname,
zc_orders_status_history.date_added,
zc_orders.date_purchased
FROM
zc_customers
INNER JOIN zc_orders ON zc_orders.customers_id = zc_customers.customers_id
INNER JOIN zc_orders_status_history ON
zc_orders_status_history.orders_id = zc_orders.orders_id
where zc_orders_status_history.orders_status_id = 8
ORDER BY zc_orders_status_history.date_added DESC
SELECT DISTINCT
zc_orders_status_history.comments,
FROM
zc_customers
INNER JOIN zc_orders ON zc_orders.customers_id = zc_customers.customers_id
INNER JOIN zc_orders_status_history ON
zc_orders_status_history.orders_id = zc_orders.orders_id
where zc_orders_status_history.orders_status_id = 8
ORDER BY zc_orders_status_history.date_added DESC
I have the following query
SELECT custconcompany, custconfirstname, custconlastname, custconemail, custconphone, shipaddress1, shipaddress2, shipcity, stateabbrv, shipzip, countryname, websitecheck.formfieldfieldvalue websitevalue, excludecheck.formfieldfieldvalue excludevalue
FROM obcisc_customers
JOIN ( (obcisc_shipping_addresses JOIN obcisc_countries
ON obcisc_shipping_addresses.shipcountryid = obcisc_countries.countryid)
LEFT JOIN obcisc_country_states
ON obcisc_shipping_addresses.shipstateid = obcisc_country_states.stateid
LEFT JOIN obcisc_formfieldsessions websitecheck
ON obcisc_shipping_addresses.shipformsessionid = websitecheck.formfieldsessioniformsessionid
LEFT JOIN obcisc_formfieldsessions excludecheck
ON obcisc_shipping_addresses.shipformsessionid = excludecheck.formfieldsessioniformsessionid)
ON obcisc_customers.customerid = obcisc_shipping_addresses.shipcustomerid
WHERE custgroupid = 11
AND websitecheck.formfieldfieldid = 24
AND excludecheck.formfieldfieldid = 30
AND excludecheck.formfieldfieldvalue != 'a:1:{i:0;s:3:"Yes";}'
ORDER BY shipstate, shipcity
This works great except I also need it to return rows where "excludecheck.formfieldfieldid=30" does not exist... right now it's not returning them
When writing a LEFT JOIN, any criteria on the table you're joining with should be put into the ON clause. If you put it into the WHERE clause, you'll filter out the results in the first table that don't have a matching row in the second table, because the NULL value that comes from the outer join will not match the criteria.
SELECT custconcompany, custconfirstname, custconlastname, custconemail, custconphone, shipaddress1, shipaddress2, shipcity, stateabbrv, shipzip, countryname, websitecheck.formfieldfieldvalue websitevalue, excludecheck.formfieldfieldvalue excludevalue
FROM obcisc_customers
JOIN obcisc_shipping_addresses
ON obcisc_customers.customerid = obcisc_shipping_addresses.shipcustomerid
JOIN obcisc_countries
ON obcisc_shipping_addresses.shipcountryid = obcisc_countries.countryid)
LEFT JOIN obcisc_country_states
ON obcisc_shipping_addresses.shipstateid = obcisc_country_states.stateid
LEFT JOIN obcisc_formfieldsessions websitecheck
ON obcisc_shipping_addresses.shipformsessionid = websitecheck.formfieldsessioniformsessionid
AND websitecheck.formfieldfieldid = 24
LEFT JOIN obcisc_formfieldsessions excludecheck
ON obcisc_shipping_addresses.shipformsessionid = excludecheck.formfieldsessioniformsessionid
AND excludecheck.formfieldfieldid = 30
AND excludecheck.formfieldfieldvalue != 'a:1:{i:0;s:3:"Yes";}')
WHERE custgroupid = 11
ORDER BY shipstate, shipcity
Another way to do it is by putting (excludecheck.formfieldfieldid = 30 OR excludecheck.formfieldfieldid IS NULL) in the WHERE clause. But this is more verbose and also I believe it's harder for MySQL to optimize, especially if you have several tables you're joining like this.
I have the following SQL query
SELECT
DISTINCT
count("SiteTree_Live"."ID")
FROM
"SiteTree_Live"
LEFT JOIN "Page_Live" ON "Page_Live"."ID" = "SiteTree_Live"."ID"
LEFT JOIN "TourPage_Live" ON "TourPage_Live"."ID" = "SiteTree_Live"."ID"
LEFT JOIN "DepartureDate" ON "DepartureDate"."TourID" = "SiteTree_Live"."ID"
WHERE
("SiteTree_Live"."Locale" = 'en_AU')
AND ("SiteTree_Live"."ClassName" IN ('TourPage'))
AND ("DepartureDate"."DepartureDate" LIKE '2012-11%')
but it producing a wrong count as the query result. The total intented result this query is suppose to return should not be more than 245 but currently, its returning more than about "4569" results.
Thats is because of the JOIN on the "DepartureDate" table as the query returns the expected result when i remove the join from the "DepartureDate" table.
What modification do i need to make to my query to count the Macthes between "SiteTree_Live"."ID" and "DepartureDate"."TourID" whiles counting only the "SiteTree_Live"."ID" count excluding the Departure dates?
Any suggestions welcomed :)
THE ANSWER
SELECT
COUNT(DISTINCT SiteTree_Live.ID)
FROM
"SiteTree_Live" LEFT JOIN "Page_Live" ON "Page_Live"."ID" = "SiteTree_Live"."ID"
LEFT JOIN "TourPage_Live" ON "TourPage_Live"."ID" = "SiteTree_Live"."ID"
LEFT JOIN "DepartureDate" ON "DepartureDate"."TourID" = "SiteTree_Live"."ID"
WHERE
("SiteTree_Live"."Locale" = 'en_AU')
AND ("SiteTree_Live"."ClassName" IN ('TourPage'))
AND ("DepartureDate"."DepartureDate" LIKE '2013-03%')
Seems to give me the right result. Thanks for the tip #Michael Berkowski
Minor correction: if DepartureDate is a date-type, then the LIKE '2013-03% will force it to be coerced into a character type (this is a mysql feature) As a result, any indexes on DepartureDate will not be used, IIRC. Better use a plain range-query:
SELECT
COUNT(DISTINCT stl.ID)
FROM
SiteTree_Live stl
LEFT JOIN
DepartureDate dd ON dd.TourID = stl.ID
WHERE
stl.Locale = 'en_AU'
AND stl.ClassName = 'TourPage'
AND dd.DepartureDate >= '2013-03-01'
AND dd.DepartureDate < '2013-04-01'
;
Do this (You have a bunch of unneeded joins)
SELECT
COUNT(DISTINCT SiteTree_Live.ID)
FROM
`SiteTree_Live`
LEFT JOIN
`DepartureDate` ON `DepartureDate`.`TourID` = `SiteTree_Live`.`ID`
WHERE
`SiteTree_Live`.`Locale` = 'en_AU'
AND `SiteTree_Live`.`ClassName` = 'TourPage'
AND `DepartureDate`.`DepartureDate` LIKE '2013-03%'
You could also do a GROUP BY:
SELECT
COUNT(SiteTree_Live.ID)
FROM
`SiteTree_Live`
LEFT JOIN
`DepartureDate` ON `DepartureDate`.`TourID` = `SiteTree_Live`.`ID`
WHERE
`SiteTree_Live`.`Locale` = 'en_AU'
AND `SiteTree_Live`.`ClassName` = 'TourPage'
AND `DepartureDate`.`DepartureDate` LIKE '2013-03%'
GROUP BY
SiteTree_Live.ID
The following query only work when I have a reference in the table wm_purchased_products.purchased_article_id but when this is empty mysql_num_rows return 0
The query is:
SELECT (SUM(wm_products_quantities.new_quantity) - SUM(wm_purchased_products.purchased_article_total) ) AS stock_restante,
wm_products_wall.nombre,
wm_products_wall.detalles,
wm_products_wall.price,
wm_products_wall.image_full,
wm_products_wall.fecha,
wm_products_wall.article_hashid
FROM wm_products_wall,
wm_products_quantities,
wm_purchased_products
WHERE wm_products_wall.categoria = '$new_rquery_xp'
AND wm_products_wall.article_hashid = wm_products_quantities.hashid_ref
AND wm_products_wall.article_hashid = wm_purchased_products.purchased_article_id
GROUP BY wm_products_wall.article_hashid
ORDER BY stock_restante ASC
How to build this query to work when I have no record in the table wm_purchased_products.purchased_article_id
Your code FROM wm_products_wall, wm_products_quantities, wm_purchased_products means all three table are INNER JOIN with each other.(that is, each and every row in the first table is joined to each and every row in the second table and so on.)
You can let wm_products_wall LEFT JOIN with wm_purchased_products, so do wm_purchased_products.
SELECT
(SUM(wm_products_quantities.new_quantity) - SUM(wm_purchased_products.purchased_article_total) ) AS stock_restante,
wm_products_wall.nombre, wm_products_wall.detalles, wm_products_wall.price,
wm_products_wall.image_full, wm_products_wall.fecha,
wm_products_wall.article_hashid
FROM wm_products_wall
LEFT OUTER JOIN wm_products_quantities
ON wm_products_wall.article_hashid = wm_products_quantities.hashid_ref
LEFT OUTER JOIN wm_purchased_products
ON wm_products_wall.article_hashid = wm_purchased_products.purchased_article_id
WHERE wm_products_wall.categoria = '$new_rquery_xp'
GROUP BY wm_products_wall.article_hashid
ORDER BY stock_restante ASC