Ho can i only fetch the rows with the highest cvID value?
current code
SELECT
CollectionVersionBlocks.cID,
CollectionVersionBlocks.cbDisplayOrder,
CollectionVersionBlocks.cvID,
btContentLocal.bID,
btContentLocal.content
FROM
CollectionVersionBlocks
INNER JOIN btContentLocal
ON CollectionVersionBlocks.bID = btContentLocal.bID
WHERE (CollectionVersionBlocks.cID = 259)
AND CollectionVersionBlocks.isOriginal = 1
AND CollectionVersionBlocks.arHandle = 'main'
AND btContentLocal.content != ''
I want to get the row at the bottom (where the cvID value is 10).
This is a test statement for a bigger result set -
I will eventually need a set of results from perset cIDs (CollectionVersionBlocks.cID = 259 OR CollectionVersionBlocks.cID = 260... upto 800)
updated screenshots
1) too few results
2) un grouped results
To get the highest row per group (from your question i assume cID as a single group) you can do so by using a self join on the maxima of your desired column by using additional condition in in your third join i.e ON(c.cID=cc.cID AND c.cvID=cc.cvID)
SELECT
c.cID,
c.cbDisplayOrder,
c.cvID,
b.bID,
b.content
FROM
CollectionVersionBlocks c
INNER JOIN btContentLocal b
ON (c.bID = b.bID)
INNER JOIN
(SELECT cID, MAX(cvID) cvID FROM CollectionVersionBlocks GROUP BY cID) cc
ON(c.cID=cc.cID AND c.cvID=cc.cvID)
WHERE (c.cID = 259)
AND c.isOriginal = 1
AND c.arHandle = 'main'
AND b.content != ''
and for multiple groups you can just use WHERE c.cID IN(259,....800)
Try below Query:
SELECT CollectionVersionBlocks.cID,CollectionVersionBlocks.cbDisplayOrder, CollectionVersionBlocks.cvID , btContentLocal.bID , btContentLocal.content
FROM CollectionVersionBlocks
INNER JOIN btContentLocal
ON CollectionVersionBlocks.bID=btContentLocal.bID
WHERE (CollectionVersionBlocks.cID = 259)
AND CollectionVersionBlocks.isOriginal=1 AND CollectionVersionBlocks.arHandle ='main' AND btContentLocal.content !='' and CollectionVersionBlocks.cID in
(
SELECT Max(CollectionVersionBlocks.cID)
FROM CollectionVersionBlocks
INNER JOIN btContentLocal
ON CollectionVersionBlocks.bID=btContentLocal.bID
WHERE (CollectionVersionBlocks.cID = 259)
AND CollectionVersionBlocks.isOriginal=1 AND CollectionVersionBlocks.arHandle ='main' AND btContentLocal.content !='' )
Related
I have following query:
SELECT
a.id_posicion,
a.profesional,
MAX( a.fecha_hora ) AS fechaPosicion,
a.latitud,
a.longitud,
b.tipo_profesional,
b.nombre,
b.apellidos,
c.tipo_profesional as tipoProfesional,
b.profile_image,
b.tel as tel,
e.especialidad as especialidad_profesional,
b.ciudad as ciudad,
b.departamento as departamento,
b.id_firebase as id_firebase
FROM tb_ultima_posicion_pro a
INNER JOIN users b ON b.id = a.profesional
INNER JOIN tb_profesionales c ON c.id_profesionales = b.tipo_profesional
INNER JOIN tb_especialidades_profesional d ON d.profesional = b.id
INNER JOIN tb_especialidades e ON d.especialidad = e.id_especialidad
GROUP BY a.profesional
ORDER BY fechaPosicion DESC
What I need is to get all records from the table tb_ultima_posicion_pro, grouped by the field profesional, which means that I get only a row for each profesional (that is ok), and for each profesional I need to get te row with the newest field fecha_hora, which is a datetime field.
What I am getting with this query is a row for each profesional (ok) but not the one with the newest fecha_hora field value.
Alternatively, You can first fetch the maximum fetch_hora by grouping the table tb_ultima_posicion_pro and then can join other tables -
SELECT a.id_posicion
,a.profesional
,am.fecha_hora AS fechaPosicion
,a.latitud
,a.longitud
,b.tipo_profesional
,b.nombre
,b.apellidos
,c.tipo_profesional as tipoProfesional
,b.profile_image
,b.tel as tel
,e.especialidad as especialidad_profesional
,b.ciudad as ciudad
,b.departamento as departamento
,b.id_firebase as id_firebase
FROM tb_ultima_posicion_pro a
INNER JOIN (SELECT profesional
,MAX(fecha_hora) AS fecha_hora
FROM tb_ultima_posicion_pro
GROUP BY profesional) am ON a.profesional = am.profesional
AND a.fecha_hora = am.fecha_hora
INNER JOIN users b ON b.id = a.profesional
INNER JOIN tb_profesionales c ON c.id_profesionales = b.tipo_profesional
INNER JOIN tb_especialidades_profesional d ON d.profesional = b.id
INNER JOIN tb_especialidades e ON d.especialidad = e.id_especialidad
ORDER BY fechaPosicion DESC
I´m trying to sum a value with the inner join. There is 4 tables that i´m using the inner join on the another table.
Table 1 = mov_estoque
Table 2 = saidas
Table 3 = produtos
Table 4 = movimento
Table 5 = nf
On table 1, there is a column EMPENHO, data I wanna sum if the column PRODUTO is the same.
My code:
select m.DATA
,n.NOTA
,p.COD_PRODUTO
,p.DESCRICAO1
,p.FATOR_CA
,sum(m.EMPENHO) as Total
from mov_estoque as m
inner join saidas as s on m.origem = s.saida
inner join produtos as p on m.produto = p.produto
inner join movimento as t on m.origem = t.cod_operacao
inner join nf as n on s.saida = n.cod_operacao
where m.DATA>'2018-10-01'
and s.filial='3'
and p.tipo_prod='AC'
and (t.evento='21' or t.evento='35')
and m.tipo_origem ='S'
and s.cancelada='F'
and n.cancelada='F'
group by m.produto
order by m.data
But this code doesn´t work, I need the sum of empenho based on the produto column.
The output that I need:
http://prntscr.com/l9gk94
DATA NOTA COD_PRODUTO DESCRICAO1 EMPENHO FATOR_CA TOTAL
02/10/2018 00:00 164406 900809 SAL DO HIMALAIA FINO (GRANEL 1KG) -1 1 0
We can use an inline view to aggregate, to precompute, a total, and then do a join.
For example, we could write a query like this, to get sum of EMPHENHO grouped by produto.
SELECT sm.produto
, SUM(sm.EMPENHO) AS sum_empenho
FROM mov_estoque sm
WHERE sm.DATA > '2018-10-01'
AND sm.tipo_origem = 'S'
GROUP
BY sm.produto
The specification for the total is unclear in the question. This is likely not the total that is desired. But this does demonstrate how we could get a sum, a single row for each value of produto.
Assuming that the rest of the query returns the detail rows that we want returned, that is, of we leave off the GROUP BY clause and the SUM aggregate:
SELECT m.DATA
, n.NOTA
, p.COD_PRODUTO
, p.DESCRICAO1
, p.FATOR_CA
FROM mov_estoque m
JOIN saidas as s on m.origem = s.saida
JOIN produtos as p on m.produto = p.produto
JOIN movimento as t on m.origem = t.cod_operacao
JOIN nf as n on s.saida = n.cod_operacao
WHERE m.DATA > '2018-10-01'
AND s.filial = '3'
AND p.tipo_prod = 'AC'
AND (t.evento='21' OR t.evento='35')
AND m.tipo_origem = 'S'
AND s.cancelada='F'
AND n.cancelada='F'
ORDER BY m.data
If that gets us the rows we want to return, and we just want to add a "total" column.
Then we could use the first query as a rowsource. Wrap it in parens and reference it the FROM clause as an inline view, with appropriate join conditions, and reference the column with the pre-aggregated total in the SELECT list. Something like this:
SELECT m.DATA
, n.NOTA
, p.COD_PRODUTO
, p.DESCRICAO1
, p.FATOR_CA
, s.sum_empenho AS total
FROM mov_estoque m
JOIN saidas as s on m.origem = s.saida
JOIN produtos as p on m.produto = p.produto
JOIN movimento as t on m.origem = t.cod_operacao
JOIN nf as n on s.saida = n.cod_operacao
JOIN ( SELECT sm.produto
, SUM(sm.EMPENHO) AS sum_empenho
FROM mov_estoque sm
WHERE sm.DATA > '2018-10-01'
AND sm.tipo_origem = 'S'
GROUP
BY sm.produto
) s
ON s.produto = m.produto
WHERE m.DATA > '2018-10-01'
AND s.filial = '3'
AND p.tipo_prod = 'AC'
AND (t.evento='21' OR t.evento='35')
AND m.tipo_origem = 'S'
AND s.cancelada='F'
AND n.cancelada='F'
ORDER BY m.data
I have the following query:
SELECT e_c.*, c.name, j.status, j.version, j.articleId, j.title FROM assetcategory AS c
INNER JOIN assetentries_assetcategories AS e_c
ON c.categoryId = e_c.categoryId AND c.name = 'news'
INNER JOIN assetentry AS e
ON e.entryId = e_c.entryId
INNER JOIN journalarticle AS j
ON j.resourcePrimKey = e.classPK
AND e.classNameId = (SELECT classNameId FROM classname_ WHERE value = 'com.liferay.portlet.journal.model.JournalArticle')
AND j.companyId= e.companyId
WHERE j.status = 0
which returns all the category news in the journalarticles. From the results I need to select the most recent versions for each articleId. For example suppose there is an article with 4 versions, even with different title, it is the same article because it will have the same articleId. So therefore for each unique articleId I need the latest version. How can I do that?
Add a join to a subquery which finds the most recent version for each article:
SELECT e_c.*, c.name, j1.status, j1.version, j1.articleId, j1.title
FROM assetcategory AS c
INNER JOIN assetentries_assetcategories AS e_c
ON c.categoryId = e_c.categoryId AND c.name = 'news'
INNER JOIN assetentry AS e
ON e.entryId = e_c.entryId
INNER JOIN journalarticle AS j1
ON j1.resourcePrimKey = e.classPK AND
e.classNameId = (SELECT classNameId FROM classname_
WHERE value = 'com.liferay.portlet.journal.model.JournalArticle') AND
j.companyId = e.companyId
INNER JOIN
(
SELECT articleId, MAX(version) AS max_version
FROM journalarticle
WHERE status = 0
GROUP BY articleId
) j2
ON j1.articleId = j2.articleId AND j1.version = j2.max_version;
The basic idea behind the join to the subquery aliased as j2 above is that it restricts the result set to only the most recent version of each article. We don't necessarily have to change the rest of the query.
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
I have a correlated subquery that will return a list of quantities, but I need the highest quantity, and only the highest. So I tried to introduce an order by and a LIMIT of 1 to achieve this, but MySQL throws an error stating it doesn't yet support limits in subqueries. Any thoughts on how to work around this?
SELECT Product.Name, ProductOption.Name, a.Qty, a.Price, SheetSize.UpgradeCost,
FinishType.Name, FinishOption.Name, FinishTierPrice.Qty, FinishTierPrice.Price
FROM `Product`
JOIN `ProductOption`
ON Product.idProduct = ProductOption.Product_idProduct
JOIN `ProductOptionTier` AS a
ON a.ProductOption_idProductOption = ProductOption.idProductOption
JOIN `PaperSize`
ON PaperSize.idPaperSize = ProductOption.PaperSize_idPaperSize
JOIN `SheetSize`
ON SheetSize.PaperSize_idPaperSize = PaperSize.idPaperSize
JOIN `FinishOption`
ON FinishOption.Product_idProduct = Product.idProduct
JOIN `FinishType`
ON FinishType.idFinishType = FinishOption.Finishtype_idFinishType
JOIN `FinishTierPrice`
ON FinishTierPrice.FinishOption_idFinishOption = FinishOption.idFinishOption
WHERE Product.idProduct = 1
AND FinishTierPrice.idFinishTierPrice IN (SELECT FinishTierPrice.idFinishTierPrice
FROM `FinishTierPrice`
WHERE FinishTierPrice.Qty <= a.Qty
ORDER BY a.Qty DESC
LIMIT 1)
This is a variation of the greatest-n-per-group problem that comes up frequently.
You want the single row form FinishTierPrice (call it p1), matching the FinishOption and with the greatest Qty, but still less than or equal to the Qty of the ProductOptionTier.
One way to do this is to try to match a second row (p2) from FinishTierPrice that would have the same FinishOption and a greater Qty. If no such row exists (use an outer join and test that it's NULL), then the row found by p1 is the greatest.
SELECT Product.Name, ProductOption.Name, a.Qty, a.Price, SheetSize.UpgradeCost,
FinishType.Name, FinishOption.Name, FinishTierPrice.Qty, FinishTierPrice.Price
FROM `Product`
JOIN `ProductOption`
ON Product.idProduct = ProductOption.Product_idProduct
JOIN `ProductOptionTier` AS a
ON a.ProductOption_idProductOption = ProductOption.idProductOption
JOIN `PaperSize`
ON PaperSize.idPaperSize = ProductOption.PaperSize_idPaperSize
JOIN `SheetSize`
ON SheetSize.PaperSize_idPaperSize = PaperSize.idPaperSize
JOIN `FinishOption`
ON FinishOption.Product_idProduct = Product.idProduct
JOIN `FinishType`
ON FinishType.idFinishType = FinishOption.Finishtype_idFinishType
JOIN `FinishTierPrice` AS p1
ON p1.FinishOption_idFinishOption = FinishOption.idFinishOption
AND p1.Qty <= a.Qty
LEFT OUTER JOIN `FinishTierPrice` AS p2
ON p2.FinishOption_idFinishOption = FinishOption.idFinishOption
AND p2.Qty <= a.Qty AND (p2.Qty > p1.Qty OR p2.Qty = p1.Qty
AND p2.idFinishTierPrice > p1.idFinishTierPrice)
WHERE Product.idProduct = 1
AND p2.idFinishTierPrice IS NULL