Subquery retunrs more than 1 row issue with JOINS - mysql

I am working on one project and facing one issue while using some joins..
I have diff tables and columns like:
tblpackages as a
packagename
packageid
stateid
packageduration
seater_4
seater_7
seater_14
tblstates as b
statename
stateid
tblpackage_packagetypes as c
packagetypeid
packageid
tblpackagetype as d
packagetypeid
packagetypename
tblpackageplaces as e
packageid
placeid
tblplaces as f
placeid
tblpackagedurations as g
packageid
days
hotelid
placeid
tblhotels as h
hotelid
and my query is as:
select a.packagename as packagename, a.packageid as packageid,
a.packageduration as days, a.seater_4, a.seater_7, a.seater_14,
b.statename,
substring_index(GROUP_CONCAT( DISTINCT (select f.placename ) SEPARATOR ',
'),',',4) placename,
substring_index(GROUP_CONCAT( DISTINCT (select d.packagetypename ) SEPARATOR
', '),',',4) packagetypename,
(select sum(g.days) from tblpackagedurations g group by a.packageid )
from tblpackages a
join tblstates b on b.stateid = a.stateid
join tblpackage_packagetypes c on c.packageid = a.packageid
join tblpackagetype d on d.packagetypeid = c.packagetypeid
join tblpackageplaces e on e.packageid = a.packageid
join tblplaces f on f.placeid = e.placeid
join tblpackagedurations g on g.packageid = a.packageid
join tblhotels h on h.hotelid = g.hotelid
where b.statename = 'jammu and kashmir'
group by a.packageid, g.packageid
and the output for days as:
packageid days
**************************
1 10
2 10
3 10
4 10
the value of days in durations as:
packageid days
**************************
1 2
2 2
3 2
4 2
4 2
the output should be
1 2
2 2
3 2
4 4
But its not as per expectation and if change group by from a.package to d i.packageid i got error as subquery returns more than 1 row

IF i have really understood your problem (difficult without see your data) you have to make aggregate function of the field you don't group by:
select a.packagename as packagename, a.packageid as packageid,
sum(a.packageduration) as days, a.seater_4, a.seater_7, a.seater_14,
b.statename,
substring_index(GROUP_CONCAT( DISTINCT (select f.placename ) SEPARATOR ',
'),',',4) placename,
substring_index(GROUP_CONCAT( DISTINCT (select d.packagetypename ) SEPARATOR
', '),',',4) packagetypename,
(select sum(g.days) from tblpackagedurations g group by a.packageid )
from tblpackages a
join tblstates b on b.stateid = a.stateid
join tblpackage_packagetypes c on c.packageid = a.packageid
join tblpackagetype d on d.packagetypeid = c.packagetypeid
join tblpackageplaces e on e.packageid = a.packageid
join tblplaces f on f.placeid = e.placeid
join tblpackagedurations g on g.packageid = a.packageid
join tblhotels h on h.hotelid = g.hotelid
where b.statename = 'jammu and kashmir'
group by a.packageid, g.packageid

Related

GROUP_CONCAT multiple where condition particular data

Query
(SELECT
pid,
visitdate,
GROUP_CONCAT(tooth, ' - ', problem, ' - ', recomendation SEPARATOR ', <br>')
FROM tbl_finds_d) V
WHERE V.pid='1' AND V.visitdate = '16-03-2020'
TABLE
Want to get WHERE pid=1 AND visitdate=16-03-2020
pid visitdate tooth problem recomendation
1 16-03-2020 13 ASX DFFF
1 16-03-2020 12 JHJ HJLP
2 12-03-2020 14 JKB IJLHJ
UPDATE (copied from the comment)
SELECT *
FROM pendingtreatment A
INNER JOIN tbl_finds_m B ON B.pid = '$pid'
AND B.visitdate = '$visitdate'
INNER JOIN treatmentadviced C ON C.pid = '$pid'
AND C.visitdate = '$visitdate'
INNER JOIN treatmentlist D ON D.pid = '$pid'
AND D.visitdate = '$visitdate'
INNER JOIN tbl_appointments E ON E.pid = '$pid'
AND E.visitdate = '$visitdate'
INNER JOIN ( SELECT pid,
visitdate,
GROUP_CONCAT(tooth, ' - ', problem, ' - ', recomendation SEPARATOR ', <br>')
FROM tbl_finds_d V
WHERE V.pid='$pid'
AND V.visitdate = '$visitdate') F
WHERE A.pid = '$pid'
AND A.visitdate = '$visitdate'

mysql combined table joins

Thank you for your comments I'll try this from a different angle.
How can this query be written to produce these results?
CompID CompeteID Casting Fishing Total
1 1 265.89 425.56 691.45
1 9 212.31 84.76 285.92
1 7 0.00 285.92 285.92
1 8 0.00 44.52 44.52
ORDER BY Total DESC
SELECT cs.CompID, ic.CompeteID
, MAX(IF(cast.CastType_ID BETWEEN 6 AND 12, cast.Length, 0)) + SUM(IF(cast.CastType_ID < 6, 40 - (cast.Length * 2), 0)) AS 'Casting'
FROM `comp-setup` cs
INNER JOIN `input-competitor` ic
ON cs.CompID = ic.Comp_ID
LEFT JOIN `input-casting` cast
ON cast.Compete_ID = ic.CompeteID
GROUP BY ic.CompeteID
UNION ALL
SELECT cs.CompID, ic.CompeteID
, SUM((iw.Weight * ca.Factor) + '1') AS 'Fishing'
FROM `comp-setup` cs
INNER JOIN `input-competitor` ic
ON cs.CompID = ic.Comp_ID
LEFT JOIN `input-weighin` iw
ON iw.Compete_ID = ic.CompeteID
INNER JOIN `input-catchpoints` ca
ON ca.PointsCatchID = iw.PointsCatch_ID
GROUP BY ic.CompeteID
Results from the above query, I have added break-line and Fishing header to separate data.
CompID CompeteID Casting
1 1 265.89
1 7 0
1 8 0
1 9 212.31
----------------------------------
Fishing
1 1 425.56
1 7 285.92
1 8 44.52
1 9 84.76
Days this has taken me to work out. I found this example today which lead me to this solution, please post if there is a better way? But this does what I need!
SELECT Sub1.CompID, Sub1.CompeteID, Sub2.Casting, Sub1.Fishing, Sub2.Casting + Sub1.Fishing AS Total
FROM
(SELECT cs.CompID, ic.CompeteID, SUM((iw.Weight * ca.Factor) + '1') AS Fishing
FROM `comp-setup` cs
INNER JOIN `input-competitor` ic ON cs.CompID = ic.Comp_ID
INNER JOIN `input-weighin` iw ON iw.Compete_ID = ic.CompeteID
INNER JOIN `input-catchpoints` ca ON ca.PointsCatchID = iw.PointsCatch_ID
INNER JOIN `list-grade` gr ON ic.Grade_ID = gr.GradeID
INNER JOIN `list-division` ld ON ic.Div_ID = ld.DivID
GROUP BY ic.CompeteID) Sub1
INNER JOIN
(SELECT cs.CompID, ic.CompeteID, MAX(IF(cast.CastType_ID BETWEEN 6 AND 12, cast.Length, 0)) + SUM(IF(cast.CastType_ID < 6, 40 - (cast.Length * 2), 0)) AS Casting
FROM `comp-setup` cs
INNER JOIN `input-competitor` ic ON cs.CompID = ic.Comp_ID
LEFT JOIN `input-casting` cast ON cast.Compete_ID = ic.CompeteID
GROUP BY ic.CompeteID) Sub2
ON Sub1.CompeteID = Sub2.CompeteID
ORDER BY Total DESC
Here is the post with the example I needed:
MYSQL LEFT JOIN with GROUP BY

mysql inner join 3 tables and union

I'm used to make queries with sparql, but i have to do this one with mysql that i don't really know the syntax.
I have these three tables:
Products:
id o
1 p1
2 p2
Specification:
id o
3 sp1
4 sp2
Source:
id o
1 s1
3 s1
2 s2
4 s2
As we see, the products and the specifications can be connected with the source different ids, so i guess i have to make 2 selects with 2 inner joins between source > product and source > specification and an inner join between the 2 selects :
SELECT * FROM
(
SELECT pt.o as po, st.id as psID, st.o as pso
FROM source_test st
inner join products_test pt on st.id = pt.id
) x INNER JOIN
(
SELECT st2.o as spo, st1.id as spsID,st1.o as spso
FROM source_test st1
inner join specification_test st2 on st1.id =st2.id
) y
This gives:
po psID pso spo spsID spso
p1 1 s1 sp1 3 s1
p2 2 s2 sp1 3 s1
p1 1 s1 sp2 4 s2
p2 2 s2 sp2 4 s2
Now i need to filter product (po) and the specification (spo) that have the same source (pso),(spso)
I'm i on doing things the right way, what could be the continuation or a good query to get:
po spo spso
p1 sp1 s1
p2 sp1 s2
Thanks in advance.
select p.o, s.o, so.o
from products p
left join specification s
left join source so on p.id=s.id and p.id = so.id;
The only thing i had to do is to to filter y ON x.pso = y.spso
SELECT * FROM
(
SELECT product.o as po, source.s as psID, source.o as pso FROM source
inner join product
on source.s = product.s
) x INNER JOIN
(
SELECT specification.o as spo, source.s as spsID, source.o as spso FROM source
inner join specification
on source.s = specification.s
) y ON x.pso = y.spso
result:
po psID pso spo spsID spso
p1 1 s1 sp1 3 s1
p2 2 s2 sp2 4 s2
Add ON x.pso = y.spso to your query:
SELECT x.po, y.spo, y.spso
FROM
(
SELECT products_test.o as po, source_test.id as psID, source_test.o as pso FROM source_test
inner join products_test
on source_test.id = products_test.id
) x INNER JOIN
(
SELECT specification_test.o as spo, source_test.id as spsID,source_test.o as spso
FROM source_test
inner join specification_test on source_test.id =specification_test.id
) y
ON x.pso = y.spso

MAX DATE with intermediate table

I can't get the right results. I have 4 tables:
table: Aluno
id_aluno nome
1 Bruno
2 Carlos
table: Serie
id_serie id_aluno descricao
1 1 Tipo A
2 1 Tipo B
3 2 Tipo A
table: Treino
id_treino id_serie data
1 1 2015-12-10
2 2 2015-12-12
3 3 2015-12-10
table: Avaliacao
id_avaliacao id_aluno data_avaliacao
1 1 2015-12-07
2 1 2015-12-01
3 2 2015-12-05
4 2 2015-12-04
I want the following results:
nome descricao data data_avaliacao
Bruno TIPO B 2015-12-12 2015-12-07
Carlos TIPO A 2015-12-10 2015-12-05
The problem is that the GROUP BY clause should have column "id_aluno" but it's not foreign key of the table which has the date. There is a intermediate table between them (serie).
And I have this other table (avaliacao) which I also want the max DATE, but when I join them all, I got more than one result by aluno.
Query I tried:
SELECT a.nome, s.descricao, t.data, aa.data_avaliacao FROM Aluno a JOIN Serie s ON s.id_aluno = a.id_aluno JOIN Treino t ON t.id_serie = s.id_serie JOIN Avaliacao aa ON aa.id_aluno = a.id_aluno WHERE t.data = SELECT MAX(t1.data) FROM Aluno a1 JOIN Serie s1 ON s1.id_aluno = a1.id_aluno JOIN Treino t1 ON t1.id_serie = s1.id_serie WHERE s1.id_aluno = s.id_aluno )
If I give you this, can you work out the other part?
SELECT a.nome
, s.descricao
, t.data
, v.data_avaliacao
FROM aluno a
JOIN serie s
ON s.id_aluno = a.id_aluno
JOIN treino t
ON t.id_serie = s.id_serie
JOIN
( SELECT s.id_aluno
, MAX(t.data) max_data
FROM serie s
JOIN treino t
ON t.id_serie = s.id_serie
GROUP
BY id_aluno
) x
ON x.id_aluno = s.id_aluno
AND x.max_data = t.data
JOIN avaliacao v
ON v.id_aluno = a.id_aluno;
working with your own query check out the last part, adding only the group by
SELECT a.nome, s.descricao, t.data, aa.data_avaliacao FROM Aluno a
JOIN Serie s ON s.id_aluno = a.id_aluno
JOIN Treino t ON t.id_serie = s.id_serie
JOIN Avaliacao aa ON aa.id_aluno = a.id_aluno
WHERE t.data =
(SELECT MAX(t1.data)
FROM Aluno a1
JOIN Serie s1 ON s1.id_aluno = a1.id_aluno
JOIN Treino t1 ON t1.id_serie = s1.id_serie
WHERE s1.id_aluno = s.id_aluno ) group by a.nome
you can test it out in sqlfiddle
I think that the code of davejal works only if coincides that in the data the MAX date of the table treino correspond to MAX date of table avaliacao for every aluno, when don´t be like that the results won´t be the expected. Using the idea of
Strawberry
, finally would be
SELECT a.nome
, s.descricao
, t.data
, v.data_avaliacao
FROM aluno a
JOIN serie s
ON s.id_aluno = a.id_aluno
JOIN treino t
ON t.id_serie = s.id_serie
JOIN
( SELECT s.id_aluno
, MAX(t.data) max_data
FROM serie s
JOIN treino t
ON t.id_serie = s.id_serie
GROUP
BY id_aluno
) x
ON x.id_aluno = s.id_aluno
AND x.max_data = t.data
JOIN avaliacao v
ON s.id_aluno = v.id_aluno
WHERE v.data_avaliacao IN
( SELECT MAX(v.data_avaliacao) max_data1
FROM avaliacao v
GROUP
BY id_aluno
)
, hope this help

How to Sum & Group By the results of a Union select query

I have a query which Union's two separate queries with the same fields / data types. The query is as follows:
SELECT BusinessUnitName, BuildingNumber, Description, Value_1,
LifeRemaining, Sum_Quant
FROM
(
SELECT bu.BusinessUnitName, b.BuildingNumber, ec.Description, SUM(cc.MonetaryValue) AS Value_1,
cc.LifeRemaining, SUM(a.Quantity) AS Sum_Quant
FROM tbBuildingLinkBusinessUnit as blb INNER JOIN
tbBusinessUnit as bu ON blb.BusinessUnitID = bu.BusinessUnitID INNER JOIN
tbBuilding as b ON blb.BuildingID = b.BuildingID INNER JOIN
tbFloor ON b.BuildingID = tbFloor.BuildingID INNER JOIN
tbRoom as r ON tbFloor.FloorID = r.FloorID INNER JOIN
tbConditionComponent as cc INNER JOIN
tbAsset as a ON cc.ParentID = a.AssetUID INNER JOIN
tbElement as e ON cc.ElementID = e.ElementID AND a.ElementID = e.ElementID INNER JOIN
tbElementCategory as ec ON e.ElementCategoryID = ec.ElementCategoryID ON r.RoomID = a.LocationID
WHERE (cc.MonetaryValue > 0)
GROUP BY bu.BusinessUnitName, b.BuildingNumber, ec.Description, a.Status, cc.LifeRemaining
HAVING (a.Status = 0)
UNION
SELECT bu.BusinessUnitName, b.BuildingNumber, ec.Description, SUM(cc.MonetaryValue) AS Value_1,
cc.LifeRemaining, SUM(a.Quantity) AS Sum_Quant
FROM tbBuildingLinkBusinessUnit as blb INNER JOIN
tbBusinessUnit as bu ON blb.BusinessUnitID = bu.BusinessUnitID INNER JOIN
tbBuilding as b ON blb.BuildingID = b.BuildingID INNER JOIN
tbConditionComponent as cc INNER JOIN
tbAsset as a ON cc.ParentID = a.AssetUID INNER JOIN
tbElement as e ON cc.ElementID = e.ElementID AND a.ElementID = e.ElementID INNER JOIN
tbElementCategory as ec ON e.ElementCategoryID = ec.ElementCategoryID ON b.BuildingID = a.LocationID
WHERE (cc.MonetaryValue > 0)
GROUP BY bu.BusinessUnitName, b.BuildingNumber, ec.Description, a.Status, cc.LifeRemaining
HAVING (a.Status = 0)
) AS x
ORDER BY BusinessUnitName, Description
The results of the individual select queries are as follows with the first two lines coming from query 1 and the second two lines coming from query 2:
TEST PROPERTY | 1/A | Electrical services | 515.82 | 0 | 3
TEST PROPERTY | 1/A | Electrical services | 125 | 1 | 2
TEST PROPERTY | 1/A | Electrical services | 381.6 | 0 | 8
TEST PROPERTY | 1/A | Electrical services | 80615.93 | 5 | 7
My question is how can I now amalgamate the results of the the two queries so that the first result from both queries perform a SUM as they both have the value 0 in column 5? This will result in 3 rows of result with rows 1 and 3 combined.
Thanks in advance
Use
Derived GROUP BY your_value
Try like below,
SELECT BusinessUnitName, BuildingNumber, Description,
LifeRemaining, SUM(Value_1) as Value, SUM(Sum_Quant) as Quant
FROM
(
SELECT bu.BusinessUnitName, b.BuildingNumber, ec.Description, SUM(cc.MonetaryValue) AS Value_1,
cc.LifeRemaining, SUM(a.Quantity) AS Sum_Quant
FROM tbBuildingLinkBusinessUnit as blb INNER JOIN
tbBusinessUnit as bu ON blb.BusinessUnitID = bu.BusinessUnitID INNER JOIN
tbBuilding as b ON blb.BuildingID = b.BuildingID INNER JOIN
tbFloor ON b.BuildingID = tbFloor.BuildingID INNER JOIN
tbRoom as r ON tbFloor.FloorID = r.FloorID INNER JOIN
tbConditionComponent as cc INNER JOIN
tbAsset as a ON cc.ParentID = a.AssetUID INNER JOIN
tbElement as e ON cc.ElementID = e.ElementID AND a.ElementID = e.ElementID INNER JOIN
tbElementCategory as ec ON e.ElementCategoryID = ec.ElementCategoryID ON r.RoomID = a.LocationID
WHERE (cc.MonetaryValue > 0)
GROUP BY bu.BusinessUnitName, b.BuildingNumber, ec.Description, a.Status, cc.LifeRemaining
HAVING (a.Status = 0)
UNION
SELECT bu.BusinessUnitName, b.BuildingNumber, ec.Description, SUM(cc.MonetaryValue) AS Value_1,
cc.LifeRemaining, SUM(a.Quantity) AS Sum_Quant
FROM tbBuildingLinkBusinessUnit as blb INNER JOIN
tbBusinessUnit as bu ON blb.BusinessUnitID = bu.BusinessUnitID INNER JOIN
tbBuilding as b ON blb.BuildingID = b.BuildingID INNER JOIN
tbConditionComponent as cc INNER JOIN
tbAsset as a ON cc.ParentID = a.AssetUID INNER JOIN
tbElement as e ON cc.ElementID = e.ElementID AND a.ElementID = e.ElementID INNER JOIN
tbElementCategory as ec ON e.ElementCategoryID = ec.ElementCategoryID ON b.BuildingID = a.LocationID
WHERE (cc.MonetaryValue > 0)
GROUP BY bu.BusinessUnitName, b.BuildingNumber, ec.Description, a.Status, cc.LifeRemaining
HAVING (a.Status = 0)
) Derived GROUP BY BusinessUnitName, BuildingNumber, Description,
LifeRemaining
ORDER BY BusinessUnitName, Description
For reference
https://social.msdn.microsoft.com/forums/sqlserver/en-US/cd32bf58-c581-404b-a384-e62cdda7a131/union-all-and-group-by-query
hope it helps...