How can I improve this query for use in large tables....?
I use a table ('DataValues') to store a collection of values ('Value') for collections ('Visit_id') ie it records certain values for each visit.
I use a table ('MatchItems') to store dynamic match sets 'MatchSet' of values ('Value'), sets can contain any number of values. The table also has a IsNeg field to indicate if the match should require a value to be not present in the visit collection.
This allows me to dynamically match visits that conform to certain criteria such as
Must contain values A, B and C and NOT D OR C and B AND NOT A.
ie (Value = A and Value = B and Value = C and Value /= D)
or (Value = C and Value = B and Value /= A)
I have a query that delivers a reasonable solution fiddle:
CREATE TABLE DataValues (
id NUMBER(5) CONSTRAINT DataValues_pk PRIMARY KEY,
Visit_id Number(5) ,
Value varchar(5)
);
INSERT INTO DataValues VALUES (1, 1, 'M');
INSERT INTO DataValues VALUES (2, 1, 'I');
INSERT INTO DataValues VALUES (3, 1, 'C');
INSERT INTO DataValues VALUES (4, 1, 'K');
INSERT INTO DataValues VALUES (5, 1, 'E');
INSERT INTO DataValues VALUES (6, 1, 'Y');
INSERT INTO DataValues VALUES (7, 2, 'M');
INSERT INTO DataValues VALUES (8, 2, 'O');
INSERT INTO DataValues VALUES (9, 2, 'U');
INSERT INTO DataValues VALUES (10, 2, 'S');
INSERT INTO DataValues VALUES (11, 2, 'E');
INSERT INTO DataValues VALUES (12, 3, 'C');
INSERT INTO DataValues VALUES (13, 3, 'A');
INSERT INTO DataValues VALUES (14, 3, 'T');
INSERT INTO DataValues VALUES (15, 4, 'S');
INSERT INTO DataValues VALUES (16, 4, 'A');
INSERT INTO DataValues VALUES (17, 4, 'T');
INSERT INTO DataValues VALUES (18, 5, 'M');
INSERT INTO DataValues VALUES (19, 5, 'A');
INSERT INTO DataValues VALUES (20, 5, 'T');
CREATE TABLE MatchItems (
id NUMBER(5) CONSTRAINT MatchItems_pk PRIMARY KEY,
MatchSet Number(5),
Value VARCHAR(5),
IsNeg NUMBER(1) NOT NULL CHECK (IsNeg in (0,1))
);
INSERT INTO MatchItems VALUES (1, 1, 'M', 0);
INSERT INTO MatchItems VALUES (2, 1, 'I', 0);
INSERT INTO MatchItems VALUES (3, 1, 'C', 0);
INSERT INTO MatchItems VALUES (4, 1, 'K', 0);
INSERT INTO MatchItems VALUES (5, 1, 'E', 0);
INSERT INTO MatchItems VALUES (6, 1, 'Y', 0);
INSERT INTO MatchItems VALUES (7, 2, 'C', 0);
INSERT INTO MatchItems VALUES (8, 2, 'A', 0);
INSERT INTO MatchItems VALUES (9, 3, 'A', 0);
INSERT INTO MatchItems VALUES (10, 3, 'T', 0);
INSERT INTO MatchItems VALUES (11, 4, 'S', 1);
INSERT INTO MatchItems VALUES (12, 4, 'A', 0);
INSERT INTO MatchItems VALUES (13, 4, 'K', 1);
INSERT INTO MatchItems VALUES (14, 5, 'A', 0);
INSERT INTO MatchItems VALUES (15, 5, 'T', 0);
SELECT
MatchItems.MatchSet,
DataValues.Visit_id,
GpMatchItems.Count TgtCount,
Count(MatchItems.Id),
sum(MatchItems.IsNeg)
FROM DataValues
LEFT JOIN MatchItems ON MatchItems.Value = DataValues.Value
--AND MatchItems.MatchSet = 4
LEFT JOIN (SELECT
MatchItems.MatchSet,
count(*) Count
FROM MatchItems
WHERE
MatchItems.IsNeg = 0
GROUP BY
MatchItems.MatchSet) GpMatchItems ON GpMatchItems.MatchSet = MatchItems.MatchSet
HAVING
Count(MatchItems.Id) = GpMatchItems.Count
AND sum(MatchItems.IsNeg) = 0
GROUP BY
MatchItems.MatchSet,
DataValues.Visit_id,
GpMatchItems.Count
How can I improve the performance of this query where the DataValues table contains 100m records, and MatchItems may include a collection of 50 sets each of 2 - 20 values?
You can try this version using Analytic functions and see if it performs any better. This query removes the subquery GpMatchItems that you are joining with.
SELECT DISTINCT matchset,
visit_id,
tgtcount,
match_visit_count,
isneg_sum
FROM (SELECT MatchItems.MatchSet,
DataValues.Visit_id,
COUNT (DISTINCT CASE MatchItems.IsNeg WHEN 0 THEN MatchItems.id ELSE NULL END)
OVER (PARTITION BY MatchItems.MatchSet)
AS tgtcount,
COUNT (*) OVER (PARTITION BY MatchItems.MatchSet, DataValues.Visit_id)
AS match_visit_count,
SUM (MatchItems.IsNeg) OVER (PARTITION BY MatchItems.MatchSet, DataValues.Visit_id)
AS isneg_sum
FROM DataValues LEFT JOIN MatchItems ON MatchItems.VALUE = DataValues.VALUE)
WHERE tgtcount = match_visit_count AND isneg_sum = 0;
I have adjusted EJ's suggestion to include a LEFT JOIN to collect the tgtCount to identify the total number of good matches required in each MatchSet:
SELECT DISTINCT matchset,
visit_id,
tgtcount,
match_visit_count,
isneg_sum
GpMatchItems.count tgtCount
FROM
COUNT (*) OVER (PARTITION BY MatchItems.MatchSet, DataValues.Visit_id)
AS match_visit_count,
SUM (MatchItems.IsNeg) OVER (PARTITION BY MatchItems.MatchSet, DataValues.Visit_id)
AS isneg_sum
FROM DataValues
LEFT JOIN MatchItems ON MatchItems.VALUE = DataValues.VALUE)
LEFT JOIN ( SELECT
MatchItems.MatchSet,
count(*) Count
FROM MatchItems
WHERE MatchItems.IsNeg = 0
GROUP BY
MatchItems.MatchSet) GpMatchItems
ON GpMatchItems.MatchSet = MatchItems.MatchSet
)
WHERE
tgtcount = match_visit_count
AND isneg_sum = 0;
My code:
drop table if exists HSstudents;
create table HSstudents
(
HSsID int,
vNAAM text,
aNAAM text,
LT int,
GM float
);
insert into HSstudents values (1, 'Thomas', 'Jansen', 18, 7.0);
insert into HSstudents values (2, 'Jesse', 'Bakker', 19, 6.5);
insert into HSstudents values (3, 'Tom', 'Smit', 20, 7.1);
insert into HSstudents values (4, 'Jelle', 'Visser', 17, 9.6);
insert into HSstudents values (5, 'Sem', 'Dekker', 17, 8.1);
insert into HSstudents values (6, 'Anna', 'Peters', 18, 6.8);
insert into HSstudents values (7, 'Michelle', 'Hendriks', 19, 8.2);
insert into HSstudents values (8, 'Senna', 'Mulder', 20, 5.9);
insert into HSstudents values (9, 'Sven', 'Linden', 21, 6.0);
insert into HSstudents values (10, 'Ilse', 'Jacobs', 21, 7.5);
insert into HSstudents values (11, 'Harm', 'Schouten', 19, 7.0);
insert into HSstudents values (12, 'Emma', 'Dijkstra', 18, 8.1);
drop table if exists students;
create table students
(
sID int,
vNAAM text,
aNAAM text,
LT int
);
insert into students values (1, 'Thomas', 'Jansen', 18);
insert into students values (2, 'Jesse', 'Bakker', 19);
insert into students values (3, 'Tom', 'Smit', 20);
insert into students values (4, 'Jelle', 'Visser', 17);
insert into students values (5, 'Sem', 'Dekker', 17);
insert into students values (6, 'Anna', 'Peters', 18);
insert into students values (7, 'Michelle', 'Hendriks', 19);
insert into students values (8, 'Senna', 'Mulder', 20);
insert into students values (9, 'Sven', 'Linden', 21);
insert into students values (10, 'Ilse', 'Jacobs', 21);
insert into students values (11, 'Harm', 'Schouten', 19);
insert into students values (12, 'Emma', 'Dijkstra', 18);
drop table if exists applications;
create table applications
(
sID int,
aPROV text,
sPROV text,
taal text
);
insert into applications values (1, 'Overijssel', 'Drenthe', 'HTML');
insert into applications values (2, 'Gelderland', 'Overijssel', 'CSS');
insert into applications values (3, 'Groningen', 'Flevoland', 'CSS');
insert into applications values (4, 'Overijssel', 'Zuid-Holland', 'SQL');
insert into applications values (5, 'Noord-Holland', 'Drenthe', 'C#');
insert into applications values (6, 'Flevoland', 'Groningen', 'C#');
insert into applications values (7, 'Limburg', 'Groningen', 'JAVA');
insert into applications values (8, 'Limburg', 'Limburg', 'JAVASCRIPT');
insert into applications values (9, 'Drenthe', 'Noord-Brabant', 'CSS');
insert into applications values (10, 'Drenthe', 'Zeeland', 'Python');
insert into applications values (11, 'Zuid-Holland', 'Friesland', 'C++');
insert into applications values (12, 'Zeeland', 'Friesland', 'JAVA');
select
S.sID, S.vNAAM, S.aNAAM, S.LT, aPROV, sPROV, taal
from
HSstudents HS, students S, applications A
where
HSstudents.HSsID = students.sID
This results in an error
Code: 1054. Unknown column 'HSstudents.HSsID' in 'where clause'
How? Shouldn't it just work?
WHERE clause should follow the remane on the FROM clause:
where HS.HSsID = S.sID
This is the following db structure i have, here the issue we are facing to order the rows based on the filed wise.
Field - table hold the field information ed, 2002,2015, Region 1 etc
IndicatorData- hold the row data
datafield - relationship with IndicatorData table... row can have multiple fields
/****** object: table [dbo].[indicatordata] ******/
create table [dbo].[indicatordata](
[id] [bigint] null,
[value] [decimal](18, 2) null,
[hopevalue] [decimal](18, 2) null,
[indicatorid] [int] null,
[datakind] [int] null
) on [primary]
go
insert [dbo].[indicatordata] ([id], [value], [hopevalue], [indicatorid], [datakind]) values (195045, cast(70.00 as decimal(18, 2)), cast(0.00 as decimal(18, 2)), 2032, 0)
insert [dbo].[indicatordata] ([id], [value], [hopevalue], [indicatorid], [datakind]) values (195046, cast(40.00 as decimal(18, 2)), cast(0.00 as decimal(18, 2)), 2032, 0)
insert [dbo].[indicatordata] ([id], [value], [hopevalue], [indicatorid], [datakind]) values (195047, cast(5.00 as decimal(18, 2)), cast(0.00 as decimal(18, 2)), 2032, 0)
insert [dbo].[indicatordata] ([id], [value], [hopevalue], [indicatorid], [datakind]) values (195048, cast(100.00 as decimal(18, 2)), cast(0.00 as decimal(18, 2)), 2032, 0)
insert [dbo].[indicatordata] ([id], [value], [hopevalue], [indicatorid], [datakind]) values (195049, cast(87.00 as decimal(18, 2)), cast(0.00 as decimal(18, 2)), 2032, 0)
insert [dbo].[indicatordata] ([id], [value], [hopevalue], [indicatorid], [datakind]) values (195050, cast(9.00 as decimal(18, 2)), cast(0.00 as decimal(18, 2)), 2032, 0)
/****** object: table [dbo].[indicator] ******/
go
create table [dbo].[indicator](
[id] [int] null,
[name] [varchar](50) null
) on [primary]
go
insert [dbo].[indicator] ([id], [name]) values (2032, n'test tile')
/****** object: table [dbo].[field] ******/
go
create table [dbo].[field](
[id] [int] null,
[name] [varchar](255) null,
[rank] [int] null,
[parentid] [int] null
) on [primary]
go
insert [dbo].[field] ([id], [name], [rank], [parentid]) values (120, n'2006', 18, 57)
insert [dbo].[field] ([id], [name], [rank], [parentid]) values (63, n'2015', 17, 57)
insert [dbo].[field] ([id], [name], [rank], [parentid]) values (303, n'2007', 9, 57)
insert [dbo].[field] ([id], [name], [rank], [parentid]) values (168, n'2018', 20, 57)
insert [dbo].[field] ([id], [name], [rank], [parentid]) values (1463, n'region 1', 1, 1459)
insert [dbo].[field] ([id], [name], [rank], [parentid]) values (1461, n'region 2', 3, 1459)
insert [dbo].[field] ([id], [name], [rank], [parentid]) values (57, n'year', 0, 0)
insert [dbo].[field] ([id], [name], [rank], [parentid]) values (1459, n'region', 0, 0)
insert [dbo].[field] ([id], [name], [rank], [parentid]) values (315, n'2002', 1, 57)
insert [dbo].[field] ([id], [name], [rank], [parentid]) values (123, n'2017', 19, 57)
/****** object: table [dbo].[datafields] ******/
set ansi_nulls on
go
create table [dbo].[datafields](
[dataid] [int] null,
[fieldid] [int] null
) on [primary]
go
insert [dbo].[datafields] ([dataid], [fieldid]) values (195045, 120)
insert [dbo].[datafields] ([dataid], [fieldid]) values (195045, 1463)
insert [dbo].[datafields] ([dataid], [fieldid]) values (195046, 63)
insert [dbo].[datafields] ([dataid], [fieldid]) values (195046, 1461)
insert [dbo].[datafields] ([dataid], [fieldid]) values (195047, 303)
insert [dbo].[datafields] ([dataid], [fieldid]) values (195047, 1463)
insert [dbo].[datafields] ([dataid], [fieldid]) values (195048, 168)
insert [dbo].[datafields] ([dataid], [fieldid]) values (195048, 1463)
insert [dbo].[datafields] ([dataid], [fieldid]) values (195049, 315)
insert [dbo].[datafields] ([dataid], [fieldid]) values (195049, 1463)
insert [dbo].[datafields] ([dataid], [fieldid]) values (195050, 123)
insert [dbo].[datafields] ([dataid], [fieldid]) values (195050, 1463)
go
Here is the query that i have tried to archive it. but its fail
select fieldid, groupedData.value as value, groupedData.hopeValue as hopeValue,
groupedData.datakind, groupedData.id as id, FieldSelector.name,
groupedData.rank
from DataFields FieldsToInsert
join (
select d.id id,min(d.datakind) as datakind, sum(rank) rank, min(value) value, min(hopeValue) hopeValue
from indicatorData d join datafields df on d.id = df.dataid
join field f on df.fieldId=f.id where indicatorId=2032
group by d.id) groupedData on FieldsToInsert.dataid = groupedData.id
join Field FieldSelector on FieldSelector.id=FieldsToInsert.fieldId
order by groupedData.rank asc, groupedData.id
Output we got it is
View Image
Expecting the output is
View image
So the first thought that strikes me is "Is the data correct?" I ask because looking at the years and rank values it suggests that 2006 should maybe be 2016 or the rank for 2006 should be 8 instead of 18.
That aside, and assuming the data is correct, you need to associate the region with the appropriate year. You can do this by getting the parent name for the field record and including the fieldid and then self joining back to get the associated year for that fieldid region record as follows...
WITH GroupedData AS
( SELECT d.id id,
min(d.datakind) AS datakind,
sum(f.rank) rank,
min(d.value) value,
min(d.hopevalue) hopeValue
FROM indicatordata d
JOIN datafields df ON d.id = df.dataid
JOIN field f ON df.fieldid = f.id
WHERE d.indicatorid = 2032
GROUP BY d.id
)
, df_parentType AS
( SELECT df.dataid,
df.fieldid,
f.name,
f.rank,
f.parentid,
fy.name AS parentname
FROM dbo.datafields AS df
JOIN field AS f ON df.fieldid = f.Id
JOIN field AS fy ON f.parentId = fy.Id
)
, df_yearregionmatched AS
( SELECT df.dataid,
df.fieldid,
df.name,
df.rank,
dfp.name AS yearname,
CASE df.parentname WHEN 'year' THEN 0 ELSE 1 END AS datafieldtype
FROM df_parentType AS df
JOIN df_parentType AS dfp ON dfp.dataid = df.dataid AND dfp.parentname = 'year'
)
SELECT GroupedData.id AS fieldid,
GroupedData.value AS value,
GroupedData.hopeValue AS hopeValue,
GroupedData.datakind,
GroupedData.id AS id,
FieldSelector.name,
GroupedData.rank,
FieldSelector.yearname,
FieldSelector.datafieldtype
FROM GroupedData
JOIN df_yearregionmatched FieldSelector ON GroupedData.id = FieldSelector.dataid
ORDER BY FieldSelector.yearname,
FieldSelector.datafieldtype;
I have used CTEs to keep the code uncomplicated. The ordering then is simply by yearname and a generated value to put year before region.
#nickFry
Check another with complex example with one more field...
create table indicator(id int not null,name varchar(255) not null)
insert indicator (id, name) values (1, 'basic employee details')
create table fields(
id int not null,
rank int,
name varchar(255) not null,
parentid int not null)
insert fields (id, rank, name, parentid) values (1, 0, 'year', 0)
insert fields (id, rank, name, parentid) values (2, 1, '2010', 1)
insert fields (id, rank, name, parentid) values (5, 2, '2011', 1)
insert fields (id, rank, name, parentid) values (6, 3, '2012', 1)
insert fields (id, rank, name, parentid) values (7, 4, '2013', 1)
insert fields (id, rank, name, parentid) values (8, 5, '2014', 1)
insert fields (id, rank, name, parentid) values (9, 0, 'nationality', 0)
insert fields (id, rank, name, parentid) values (10, 1, 'libya', 9)
insert fields (id, rank, name, parentid) values (11, 2, 'ukrine', 9)
insert fields (id, rank, name, parentid) values (12, 0, 'gender', 0)
insert fields (id, rank, name, parentid) values (13, 1, 'male', 12)
insert fields (id, rank, name, parentid) values (14, 2, 'fe male', 12)
insert fields (id, rank, name, parentid) values (15, 0, 'maritalstatus', 0)
insert fields (id, rank, name, parentid) values (16, 1, 'married', 15)
insert fields (id, rank, name, parentid) values (17, 2, 'unmarried', 15)
insert fields (id, rank, name, parentid) values (18, 3, 'divorced', 15)
create table indicatorfields(
indicatorid int not null,
fieldid int not null,rank int)
insert indicatorfields (indicatorid, fieldid,rank) values (1, 2,1)
insert indicatorfields (indicatorid, fieldid,rank) values (1, 5,1)
insert indicatorfields (indicatorid, fieldid,rank) values (1, 6,1)
insert indicatorfields (indicatorid, fieldid,rank) values (1, 7,1)
insert indicatorfields (indicatorid, fieldid,rank) values (1, 8,1)
insert indicatorfields (indicatorid, fieldid,rank) values (1, 10,3)
insert indicatorfields (indicatorid, fieldid,rank) values (1, 11,3)
insert indicatorfields (indicatorid, fieldid,rank) values (1, 16,2)
insert indicatorfields (indicatorid, fieldid,rank) values (1, 17,2)
insert indicatorfields (indicatorid, fieldid,rank) values (1, 18,2)
create table indicatordata(
dataid int not null,
value varchar(255) not null,
indicatorid int not null)
insert indicatordata (dataid, value, indicatorid) values (1, '1015', 1)
insert indicatordata (dataid, value, indicatorid) values (2, '15', 1)
insert indicatordata (dataid, value, indicatorid) values (3, '12', 1)
insert indicatordata (dataid, value, indicatorid) values (4, '187', 1)
insert indicatordata (dataid, value, indicatorid) values (5, '50', 1)
insert indicatordata (dataid, value, indicatorid) values (6, '65', 1)
create table datafields(
dataid int not null,
fieldid int not null)
insert datafields (dataid, fieldid) values (1, 8)
insert datafields (dataid, fieldid) values (1, 10)
insert datafields (dataid, fieldid) values (1, 16)
insert datafields (dataid, fieldid) values (2, 6)
insert datafields (dataid, fieldid) values (2, 11)
insert datafields (dataid, fieldid) values (2, 17)
insert datafields (dataid, fieldid) values (3, 7)
insert datafields (dataid, fieldid) values (3, 11)
insert datafields (dataid, fieldid) values (3, 17)
insert datafields (dataid, fieldid) values (4, 2)
insert datafields (dataid, fieldid) values (4, 11)
insert datafields (dataid, fieldid) values (4, 16)
insert datafields (dataid, fieldid) values (5, 8)
insert datafields (dataid, fieldid) values (5, 10)
insert datafields (dataid, fieldid) values (5, 18)
insert datafields (dataid, fieldid) values (6, 2)
insert datafields (dataid, fieldid) values (6, 10)
insert datafields (dataid, fieldid) values (6, 16)
We need to get rows based on the indicatorfield & fields table order by rank
See the attached image for
Actual Output
This is wat i am looking for
Expected OutPut
#Prasad, solution without reference to any hardcoded data value...
WITH GroupedData AS
( SELECT d.dataid id,
--min(d.datakind) AS datakind,
sum(f.rank) rank,
min(d.value) value --,
--min(d.hopevalue) hopeValue
FROM indicatordata d
JOIN datafields df ON d.dataid = df.dataid
JOIN fields f ON df.fieldid = f.id
WHERE d.indicatorid = 1
GROUP BY d.dataid
)
, df_parentType AS
( SELECT df.dataid,
df.fieldid,
f.name,
f.rank,
f.parentid,
fy.name AS parentname
FROM dbo.datafields AS df
JOIN fields AS f ON df.fieldid = f.Id
JOIN fields AS fy ON f.parentId = fy.Id
)
, df_parentmatched AS
( SELECT df.dataid,
df.fieldid,
df.name,
df.rank,
dfp.name AS parentname
FROM df_parentType AS df
JOIN df_parentType AS dfp ON dfp.dataid = df.dataid AND dfp.parentname = (SELECT DISTINCT parentname FROM df_parentType WHERE parentid = (SELECT min(dataid) FROM df_parentType))
)
SELECT GroupedData.id AS datadid,
GroupedData.value AS value,
--GroupedData.hopeValue AS hopeValue,
--GroupedData.datakind,
FieldSelector.fieldid,
FieldSelector.name,
GroupedData.rank,
FieldSelector.parentname
FROM GroupedData
JOIN df_parentmatched FieldSelector ON GroupedData.id = FieldSelector.dataid
ORDER BY FieldSelector.parentname,
GroupedData.rank,
FieldSelector.fieldid;
#nickFy
The one you provide is fine... With this complex example... expected order is not coming in the correct way
Here is another complex example without the year
insert indicator (id, name) values (2, 'testing employee details 2')
insert indicatorfields (indicatorid, fieldid,rank) values (2, 10,3)
insert indicatorfields (indicatorid, fieldid,rank) values (2, 11,3)
insert indicatorfields (indicatorid, fieldid,rank) values (2, 13,1)
insert indicatorfields (indicatorid, fieldid,rank) values (2, 14,1)
insert indicatorfields (indicatorid, fieldid,rank) values (2, 16,2)
insert indicatorfields (indicatorid, fieldid,rank) values (2, 17,2)
insert indicatorfields (indicatorid, fieldid,rank) values (2, 18,2)
insert indicatordata (dataid, value, indicatorid) values (7, '1015', 2)
insert indicatordata (dataid, value, indicatorid) values (8, '15', 2)
insert indicatordata (dataid, value, indicatorid) values (9, '12', 2)
insert indicatordata (dataid, value, indicatorid) values (10, '187', 2)
insert indicatordata (dataid, value, indicatorid) values (11, '50', 2)
insert datafields (dataid, fieldid) values (7, 11)
insert datafields (dataid, fieldid) values (7, 13)
insert datafields (dataid, fieldid) values (7, 16)
insert datafields (dataid, fieldid) values (8, 10)
insert datafields (dataid, fieldid) values (8, 13)
insert datafields (dataid, fieldid) values (8, 17)
insert datafields (dataid, fieldid) values (9, 10)
insert datafields (dataid, fieldid) values (9, 14)
insert datafields (dataid, fieldid) values (9, 18)
insert datafields (dataid, fieldid) values (10, 11)
insert datafields (dataid, fieldid) values (10, 13)
insert datafields (dataid, fieldid) values (10, 16)
insert datafields (dataid, fieldid) values (11, 10)
insert datafields (dataid, fieldid) values (11, 14)
insert datafields (dataid, fieldid) values (11, 16)
**Acutal Output we got is **
select a.dataid,value,df.fieldid,name from indicatordata a INNER JOIN datafields df on a.dataid=df.dataid
INNER JOIN fields f ON df.fieldid=f.id INNER JOIN indicatorfields indFields ON indFields.fieldid=df.fieldid
where a.indicatorid=2 and indFields.indicatorid=2 order by a.dataid
We need to order the fields based on the indicatorfield & field table
Expected Output should be like this