MYSQL UNION and ORDER BY not working - mysql

I have a mysql query which is as follows
(SELECT order_product.op_id,
order_product.ocat_id,
order_product.op_partnunber,
order_product.op_name,
order_product.op_upc,
order_product.op_desc,
order_stockavailable.osa_id,
order_stockavailable.of_id,
order_stockavailable.osa_stocka,
order_category.ocat_name
FROM
order_product
LEFT JOIN order_category
ON order_product.ocat_id = order_category.ocat_id
LEFT JOIN order_stockavailable
ON order_product.op_id = order_stockavailable.op_id)
UNION
(SELECT order_product.op_id,
order_product.ocat_id,
order_product.op_partnunber,
order_product.op_name,
order_product.op_upc,
order_product.op_desc,
order_stockavailable_attributes.id,
order_stockavailable_attributes.of_id,
order_stockavailable_attributes.opap_stock,
order_category.ocat_name
FROM order_product
LEFT JOIN order_category
ON order_product.ocat_id = order_category.ocat_id
LEFT JOIN order_stockavailable
ON order_product.op_id = order_stockavailable.op_id
LEFT JOIN order_stockavailable_attributes
ON order_product.op_id = order_stockavailable_attributes.op_id)
ORDER BY order_product.op_name
The query is givng error, T
Table 'order_product' from one of the SELECTs cannot be used in global ORDER clause
I checked the MYSQL manual, but am not getting any clue, any help would be really great.

SELECT *
FROM (
SELECT order_product.op_id,
order_product.ocat_id,
order_product.op_partnunber,
order_product.op_name,
order_product.op_upc,
order_product.op_desc,
order_stockavailable.osa_id,
order_stockavailable.of_id,
order_stockavailable.osa_stocka,
order_category.ocat_name
FROM
order_product
LEFT JOIN order_category
ON order_product.ocat_id = order_category.ocat_id
LEFT JOIN order_stockavailable
ON order_product.op_id = order_stockavailable.op_id
UNION
SELECT order_product.op_id,
order_product.ocat_id,
order_product.op_partnunber,
order_product.op_name,
order_product.op_upc,
order_product.op_desc,
order_stockavailable_attributes.id,
order_stockavailable_attributes.of_id,
order_stockavailable_attributes.opap_stock,
order_category.ocat_name
FROM order_product
LEFT JOIN order_category
ON order_product.ocat_id = order_category.ocat_id
LEFT JOIN order_stockavailable
ON order_product.op_id = order_stockavailable.op_id
LEFT JOIN order_stockavailable_attributes
ON order_product.op_id = order_stockavailable_attributes.op_id
) t
ORDER BY op_name
Btw: there is no need to put the individual SELECTs of a UNION into brackets.

Try the following syntax?
SELECT
x, y
FROM
(
SELECT x, y FROM z
UNION
SELECT a, b FROM c
)
ORDER BY
x, y

Try
order by op_name
instead of
ORDER BY order_product.op_name

SELECT *
FROM (SELECT order_product.op_id,
...
FROM
... )
UNION
(SELECT order_product.op_id,
...
FROM order_product
... ) U
ORDER BY op_name;

Related

bring the last 10 orders whitout repeating

I have the following query
SELECT a.id, a.fecha, a.ser, a.numero, c.nombre_apellido, a.estado, a.tipo, a.articulo, a.precio_asignado, a.retirada, a.pronta, a.precio, a.confirmada, d.marca, a.modelo, a.fecha_prometido, a.fecha_asignado, a.presupuesto, a.cant_llamados
FROM (
(
(
ordenes_servicio_bitacora b
LEFT JOIN ordenes_reparaciones a ON b.id_orden = a.id
)
LEFT JOIN clientes c ON a.cliente_id = c.id
)
LEFT JOIN marcas d ON a.marca_id = d.id
)
ORDER BY b.id_bitacora DESC
LIMIT 10
and it brings me this
as you see the id column of the order is repeated because of the cross with bitacora table i need not to be repeated, any ideas? Thanks in advance.
DISTINCT should do the job in your case, as all the columns' data are repeated for the row not just the id column:
SELECT DISTINCT
a.id, a.fecha, a.ser, a.numero,
c.nombre_apellido, a.estado,
a.tipo, a.articulo, a.precio_asignado,
a.retirada, a.pronta, a.precio,
a.confirmada, d.marca, a.modelo,
a.fecha_prometido, a.fecha_asignado,
a.presupuesto, a.cant_llamados
FROM ordenes_servicio_bitacora b
LEFT JOIN ordenes_reparaciones a ON b.id_orden = a.id
LEFT JOIN clientes c ON a.cliente_id = c.id
LEFT JOIN marcas d ON a.marca_id = d.id
ORDER BY b.id_bitacora DESC
LIMIT 10
SELECT a.id, a.fecha, a.ser, a.numero, c.nombre_apellido, a.estado, a.tipo, a.articulo, a.precio_asignado, a.retirada, a.pronta, a.precio, a.confirmada, d.marca, a.modelo, a.fecha_prometido, a.fecha_asignado, a.presupuesto, a.cant_llamados
FROM (
(
(
(SELECT DISTINCT id_orden
FROM `ordenes_servicio_bitacora`
ORDER BY id_bitacora DESC
LIMIT 10) b
LEFT JOIN ordenes_reparaciones a ON b.id_orden = a.id
)
LEFT JOIN clientes c ON a.cliente_id = c.id
)
LEFT JOIN marcas d ON a.marca_id = d.id
)
i just made a subquery and the job is done, thanks by the answers and comments :)

Getting the latest date from a id

I run the above sql statement and i got this.[IMG]http://i1093.photobucket.com/albums/i422/walkgirl_1993/asd-1_zps5506632e.jpg[/IMG] i'm trying display the latest date which you can see the 3 and 4. For caseid 3, it should display the latest row which is the 2012-12-20 16:12:36.000. I tried using group by, order by. Google some website said to use rank but i'm not sure about the rank as i dont really get rank. Some suggestions?
select [Case].CaseID, Agent.AgentName, Assignment.Description, A.AgentName as EditedBy, A.DateEdited from Agent inner join [Case-Agent] on [Case-Agent].AgentID = Agent.AgentID inner join [Assignment] on Assignment.AssignmentID = [Case-Agent].AssignmentID inner join [Case] on [Case].CaseID = [Case-Agent].CaseID inner join (select EditedCase.CaseID, [EditedCase].DateEdited, [Agent].AgentName from EditedCase inner join [Agent] on [Agent].AgentID = [EditedCase].AgentID) A on A.CaseID = [Case].CaseID where [Assignment].AssignmentID = 0
To do it using RANK you just need to add the RANK to the subquery and get to rank the DateEdited for each CaseID and Agent and then in the main query put a WHERE clause to only select rows where the rank is 1. I think I have got the partition clause right - its a bit hard without seeing your data.
Like this:
SELECT
[Case].CaseID
,Agent.AgentName
,Assignment.Description
,A.AgentName AS EditedBy
,A.DateEdited
FROM Agent
INNER JOIN [Case-Agent] ON [Case-Agent].AgentID = Agent.AgentID
INNER JOIN [Assignment] ON Assignment.AssignmentID = [Case-Agent].AssignmentID
INNER JOIN [Case] ON [Case].CaseID = [Case-Agent].CaseID
INNER JOIN (SELECT
EditedCase.CaseID
,[EditedCase].DateEdited
,[Agent].AgentName
,RANK ( ) OVER (PARTITION BY EditedCase.CaseID, [Agent].AgentName
ORDER BY [EditedCase].DateEdited DESC ) AS pos
FROM EditedCase
INNER JOIN [Agent] on [Agent].AgentID = [EditedCase].AgentID) A on A.CaseID = [Case].CaseID
WHERE [Assignment].AssignmentID = 0
AND pos = 1
You could also change the sub query into an aggregate query that brings back the MAX date like this:
SELECT
[Case].CaseID
,Agent.AgentName
,Assignment.Description
,A.AgentName AS EditedBy
,A.DateEdited
FROM Agent
INNER JOIN [Case-Agent] ON [Case-Agent].AgentID = Agent.AgentID
INNER JOIN [Assignment] ON Assignment.AssignmentID = [Case-Agent].AssignmentID
INNER JOIN [Case] ON [Case].CaseID = [Case-Agent].CaseID
INNER JOIN (SELECT
EditedCase.CaseID
,MAX([EditedCase].DateEdited) AS DateEdited
,[Agent].AgentName
FROM EditedCase
INNER JOIN [Agent] on [Agent].AgentID = [EditedCase].AgentID
GROUP BY
EditedCase.CaseID
,[Agent].AgentName) A on A.CaseID = [Case].CaseID
WHERE [Assignment].AssignmentID = 0
AND pos = 1
You were on the right track; you need to use a ranking function here, for example row_number():
with LatestCase as
(
select [Case].CaseID
, Agent.AgentName
, Assignment.Description
, A.AgentName as EditedBy
, A.DateEdited
, caseRank = row_number() over (partition by [Case].CaseID order by A.DateEdited desc)
from Agent
inner join [Case-Agent] on [Case-Agent].AgentID = Agent.AgentID
inner join [Assignment] on Assignment.AssignmentID = [Case-Agent].AssignmentID
inner join [Case] on [Case].CaseID = [Case-Agent].CaseID
inner join
(
select EditedCase.CaseID
, [EditedCase].DateEdited
, [Agent].AgentName
from EditedCase
inner join [Agent] on [Agent].AgentID = [EditedCase].AgentID
) A on A.CaseID = [Case].CaseID where [Assignment].AssignmentID = 0
)
select *
from LatestCase
where caseRank = 1

Using JOIN sql query

I would like to use JOIN instead of IN in the following SQL query. I can't figure out how to do it.
SELECT * FROM shop_orders WHERE
id IN (SELECT orders_id FROM shop_orders_data WHERE closed='1' /*AND backorder='0'*/ AND exhibition_id='389' AND
exhibition_id IN (SELECT id FROM shop_exhibitions WHERE
country_id IN (SELECT id FROM countries WHERE id='72')) AND in_country = '72' AND
exhibition_id IN (SELECT id FROM shop_exhibitions WHERE start<=1336946400 AND end>1336600800)) AND
id IN (SELECT orders_id FROM shop_orders_products WHERE
products_id IN (SELECT id FROM shop_products WHERE artno='120000' OR name LIKE '%120000%')) AND created>=1333231200 AND created<1333663200 ORDER BY created DESC
I tried this:
SELECT
s.*
FROM
shop_orders s
INNER JOIN shop_orders_data od ON s.id=od.orders_id
INNER JOIN shop_exhibitions se ON od.exhibition_id=se.id
INNER JOIN countries co ON se.country_id=co.id
INNER JOIN shop_orders_products sop ON s.id=sop.orders_id
INNER JOIN shop_products sp
ON sop.products_id=sp.id
WHERE od.closed=1
AND ( sp.artno='120000' or sp.name LIKE '%120000%' )
AND ( od.exhibition_id='389')
AND ( od.in_country = '72')
AND ( se.start <=1336946400)
AND ( se.end >1336600800)
AND ( se.created>=1333231200)
AND ( se.created<1333663200)
ORDER BY `s`.`created` DESC
I this correct??
See if this works (and study the code to learn how it works):
SELECT *
FROM shop_orders so
JOIN shop_orders_data sod ON (
(so.id = sod.orders_id)
AND (sod.closed = '1')
/*AND (sod.backorder = '0') */
AND (sod.exhibition_id = '389')
AND (sod.in_country = '72')
)
JOIN shop_exhibitions se ON (
(sod.exhibition_id = se.id)
AND (se.start <= 1336946400)
AND (se.end > 1336600800)
)
JOIN countries c ON (
(se.country_id = c.id)
AND (c.id = '72')
)
JOIN shop_orders_products sop ON (
(so.id = sop.orders_id)
)
JOIN shop_products sp ON (
(sop.products_id = sp.id)
AND ((sp.artno='120000') OR (sp.name LIKE '%120000%'))
)
WHERE (so.created >= 1333231200) AND (so.created < 1333663200)
ORDER BY so.created DESC;
The join syntax works like this:
SELECT field1,field2,field3
FROM FirstTable
JOIN SecondTable ON (FirstTable.PrimaryKey = SecondTable.ForeignKey)
JOIN ThirdTable ON (FirstTable.PrimaryKey = ThirdTable.ForeignKey)
Try applying this approach to your query.

I am using UNION ALL, then I want ORDER BY globaly

Can I order by flt.flt_Date_Start(Globaly union) If its there any solution please help me
Here I try to achieve order by Date Globally Please Help me
Can I order by flt.flt_Date_Start(Globaly union) If its there any solution please help me
Here I try to achieve order by Date Globally Please Help me
Can I order by flt.flt_Date_Start(Globaly union) If its there any solution please help me
Here I try to achieve order by Date Globally Please Help me
(Select
flt.flt_Id as fltId,
flttyp.flttyp_Name As FlightType,
off.off_Name as offName,
fltrte.fltrte_P1_Plt_Per_Id_Fk As pilot1Id,
fltrte.fltrte_P2_Plt_Per_Id_Fk As pilot2Id,
per1.per_Name As Pilot1Name,
per2.per_Name As Pilot2Name,
per1.per_Name As GrpPilotName,
flt.flt_Date_Start as dtStrt,
flt.flt_Date_End as dtEnd,
air.air_Id as airId,
flt.flt_Trip_Rpt_No as rptNo,
flttyp.flttyp_Id as flttypId,
flt.flt_Eng_Tim As EngT,
flt.flt_Flt_Tim As FlyT,
flt.flt_Wait_Tim As WaitT,
(select sum(pltfltdtytim.pltfltdtytim_Tot_Dty_Tim) from pltfltdtytim where pltfltdtytim.pltfltdtytim_Flt_Id_Fk = flt.flt_Id and pltfltdtytim.pltfltdtytim_Per_Id_Fk=per1.per_Id) As DutyT,
flt.flt_Route as fltRout
From
fltrte left Join
flt On fltrte.fltrte_Flt_Id_Fk = flt.flt_Id left Join
off On flt.flt_Off_Id_Fk = off.off_Id left Join
air On flt.flt_Air_Id_Fk = air.air_Id left Join
per per1 On fltrte.fltrte_P1_Plt_Per_Id_Fk = per1.per_Id left Join
per per2 On fltrte.fltrte_P2_Plt_Per_Id_Fk = per2.per_Id left join
flttyp On flt.flt_Flttyp_Id_Fk = flttyp.flttyp_Id
where
flt.flt_Status <> 4 and per1.per_Name is not null and per1.per_Name !=''
Group By
off.off_Name,flt.flt_Date_Start,
flt.flt_Trip_Rpt_No, flt.flt_Id, flttyp.flttyp_Name, flt.flt_Route,
flt.flt_Status
Order By
flt.flt_Date_Start)
union all
(Select
flt.flt_Id as fltId,
flttyp.flttyp_Name As FlightType,
off.off_Name as offName,
fltrte.fltrte_P1_Plt_Per_Id_Fk As pilot1Id,
fltrte.fltrte_P2_Plt_Per_Id_Fk As pilot2Id,
per1.per_Name As Pilot1Name,
per2.per_Name As Pilot2Name,
per2.per_Name As GrpPilotName,
flt.flt_Date_Start as dtStrt,
flt.flt_Date_End as dtEnd,
air.air_Id as airId,
flt.flt_Trip_Rpt_No as rptNo,
flttyp.flttyp_Id as flttypId,
flt.flt_Eng_Tim As EngT,
flt.flt_Flt_Tim As FlyT,
flt.flt_Wait_Tim As WaitT,
(select sum(pltfltdtytim.pltfltdtytim_Tot_Dty_Tim) from pltfltdtytim where pltfltdtytim.pltfltdtytim_Flt_Id_Fk = flt.flt_Id and pltfltdtytim.pltfltdtytim_Per_Id_Fk=per2.per_Id) As DutyT,
flt.flt_Route as fltRout
From
fltrte left Join
flt On fltrte.fltrte_Flt_Id_Fk = flt.flt_Id left Join
off On flt.flt_Off_Id_Fk = off.off_Id left Join
air On flt.flt_Air_Id_Fk = air.air_Id left Join
per per1 On fltrte.fltrte_P1_Plt_Per_Id_Fk = per1.per_Id left Join
per per2 On fltrte.fltrte_P2_Plt_Per_Id_Fk = per2.per_Id left join
flttyp On flt.flt_Flttyp_Id_Fk = flttyp.flttyp_Id
where
flt.flt_Status <> 4 and per2.per_Name is not null and per2.per_Name !=''
Group By
off.off_Name,flt.flt_Date_Start,
flt.flt_Trip_Rpt_No, flt.flt_Id, flttyp.flttyp_Name, flt.flt_Route,
flt.flt_Status
Order By
flt.flt_Date_Start)
You only need to do a subselect:
SELECT ... dtStrt ...
FROM (
(SELECT ... as dtStrt, ...
FROM ... JOIN... WHERE...)
union all
(SELECT ... as dtStrt, ...
FROM ... JOIN... WHERE...)
) as val
ORDER BY dtStrt

SQL Query Problem

I've been at this for a bit now. Basically, I'm needing to add a derived column to count the hits to a weblog entry in the database. The problem is, the hits are being totaled and shown on only on the first record. Any Ideas? I've emboldened the parts of the query I'm talking about. The query is below:
SELECT DISTINCT(t.entry_id),
exp_categories.rank,
**exp_hits.hits,**
t.entry_id,
t.weblog_id,
t.forum_topic_id,
t.author_id,
t.ip_address,
t.title,
t.url_title,
t.status,
t.dst_enabled,
t.view_count_one,
t.view_count_two,
t.view_count_three,
t.view_count_four,
t.allow_comments,
t.comment_expiration_date,
t.allow_trackbacks,
t.sticky,
t.entry_date,
t.year,
t.month,
t.day,
t.entry_date,
t.edit_date,
t.expiration_date,
t.recent_comment_date,
t.comment_total,
t.trackback_total,
t.sent_trackbacks,
t.recent_trackback_date,
t.site_id as entry_site_id,
w.blog_title,
w.blog_name,
w.search_results_url,
w.search_excerpt,
w.blog_url,
w.comment_url,
w.tb_return_url,
w.comment_moderate,
w.weblog_html_formatting,
w.weblog_allow_img_urls,
w.weblog_auto_link_urls,
w.enable_trackbacks,
w.trackback_use_url_title,
w.trackback_field,
w.trackback_use_captcha,
w.trackback_system_enabled,
m.username,
m.email,
m.url,
m.screen_name,
m.location,
m.occupation,
m.interests,
m.aol_im,
m.yahoo_im,
m.msn_im,
m.icq,
m.signature,
m.sig_img_filename,
m.sig_img_width,
m.sig_img_height,
m.avatar_filename,
m.avatar_width,
m.avatar_height,
m.photo_filename,
m.photo_width,
m.photo_height,
m.group_id,
m.member_id,
m.bday_d,
m.bday_m,
m.bday_y,
m.bio,
md.*,
wd.*
FROM exp_weblog_titles AS t
LEFT JOIN exp_weblogs AS w ON t.weblog_id = w.weblog_id
LEFT JOIN exp_weblog_data AS wd ON t.entry_id = wd.entry_id
LEFT JOIN exp_members AS m ON m.member_id = t.author_id
LEFT JOIN exp_member_data AS md ON md.member_id = m.member_id
LEFT JOIN exp_category_posts ON wd.entry_id = exp_category_posts.entry_id
**LEFT JOIN
(
SELECT COUNT(*) AS hits, exp_hits.entry_id FROM exp_hits ORDER BY exp_hits.entry_id
) exp_hits ON t.entry_id = exp_hits.entry_id**
LEFT JOIN
(
SELECT exp_categories.cat_id, cat_name as rank
FROM exp_categories
WHERE exp_categories.group_id = '9'
) exp_categories ON exp_categories.cat_id = exp_category_posts.cat_id
WHERE t.entry_id IN (2,3,4) ORDER BY exp_categories.rank DESC, **exp_hits.hits DESC**, entry_date desc
Try changeing the subselect to
SELECT COUNT(*) AS hits,
exp_hits.entry_id
FROM exp_hits
GROUP BY exp_hits.entry_id
Out of curiosity, is your hits functionality something that can't be accomplished with the view_count_one/two/three/four fields already present in the database and supported by ExpressionEngine template tags?