linq2sql with group and joins - vb.net

How would one write this query in linq (VB)
select
g.*
from PROB_GROUP g
inner join
(
select
PGR_NAME,
PGR_PCELL,
max(PGR_VERSION) max_version
from PROB_GROUP
group by PGR_NAME, PGR_PCELL
) grouped_g
on g.PGR_NAME = grouped_g.PGR_NAME
and g.PGR_PCELL = grouped_g.PGR_PCELL
and g.PGR_VERSION = grouped_g.max_version
order by g.PGR_TYPE, g.PGR_NAME

got it
From pp In DB.PROB_GROUPs Join p1 In
(From p In DB.PROB_GROUPs Group By p.PGR_NAME, p.PGR_PCELL Into g = Group Select PGR_NAME, PGR_PCELL, H_VERSION = g.Max(Function(p) p.PGR_VERSION))
On p1.H_VERSION Equals pp.PGR_VERSION And p1.PGR_NAME Equals pp.PGR_NAME And p1.PGR_PCELL Equals pp.PGR_PCELL Select pp Order By pp.PGR_TYPE, pp.PGR_NAME
Should be ok right?

Related

select top 1 in subquery?

I'm trying to get a top 1 returned for each code in this query but this is giving me syntax errors. Any ideas what I can do?
SELECT d.doc_no,
d.doc_short_name,
d.doc_name,
r.revision_code,
r.revision,
r.description,
dtg.group_name,
(SELECT top 1 di.index_user_id
FROM document_instance
WHERE doc_no = d.doc_no
ORDER BY entry_time DESC) AS 'last indexed by'
FROM documents d
LEFT JOIN document_revision r ON r.doc_no = d.doc_no
LEFT JOIN document_instance di ON di.doc_no = d.doc_no
LEFT JOIN document_type_group dtg ON dtg.doc_no = d.doc_no
Assuming Sybase ASE, the top # clause is only supported in derived tables, ie, it's not supported in correlated sub-queries like you're attempting.
Also note that order by is not supported in any sub-queries (derived table or correlated).
If I'm reading the query correctly, you want the index_user_id for the record with the max(entry_time); if this is correct, and assuming a single record is returned for a given doc_no/entry_time combo, you could try something like:
SELECT d.doc_no,
d.doc_short_name,
d.doc_name,
r.revision_code,
r.revision,
r.description,
dtg.group_name,
(SELECT d2.index_user_id
FROM document_instance d2
WHERE d2.doc_no = d1.doc_no
and d2.entry_time = (select max(d3.entry_time)
from document_instance d3
where d3.doc_no = d1.doc_no)
) as 'last indexed by'
FROM documents d
LEFT JOIN document_revision r ON r.doc_no = d.doc_no
LEFT JOIN document_instance d1 ON d1.doc_no = d.doc_no
LEFT JOIN document_type_group dtg ON dtg.doc_no = d.doc_no

SQL Selecting rows with not the same condition for all

I have to create SQL query that select persons datas. Every person has several grades and I have to select first by time for everyone. I don't know how do it because conditional is different for every person. Below is my current code which doesn't works.
SELECT s.sol_last_name,
g.grade_name,
MIN(sg.sol_grade_date_from)
FROM [dbo].[dim_s####] AS s
LEFT JOIN [dbo].[fact_s####_grade] AS sg ON s.sol_key = sg.sol_grade_sollers_key
LEFT JOIN [dbo].[dim_grade] AS g ON g.grade_key = sg.sol_grade_grade_key
GROUP BY s.sol_last_name,
g.grade_name
HAVING MIN(sg.sol_grade_date_from) = sg.sol_grade_date_from
You can put the earliest date in a subquery, and then inner join there:
SELECT s.sol_last_name,
g.grade_name,
sg.sol_grade_date_from
FROM [dbo].[dim_s####] AS s
INNER JOIN (
select sol_grade_grade_key
,min(sol_grade_date_from) as sol_grade_date_
from from [dbo].[dim_grade]
GROUP BY sol_grade_grade_key) AS g
ON g.grade_key = sg.sol_grade_grade_key
LEFT JOIN [dbo].[fact_s####_grade] AS sg
ON s.sol_key = sg.sol_grade_sollers_key
Use a Common Table Expression (cte) to save some typing. Then do a NOT EXISTS to return a row only if same sol_last_name has no older grade.
WITH CTE (sol_last_name, grade_name, grade_date_from) AS
(
SELECT s.sol_last_name,
g.grade_name,
sg.sol_grade_date_from
FROM [dbo].[dim_s####] AS s
LEFT JOIN [dbo].[fact_s####_grade] AS sg ON s.sol_key = sg.sol_grade_sollers_key
LEFT JOIN [dbo].[dim_grade] AS g ON g.grade_key = sg.sol_grade_grade_key
)
select sol_last_name, grade_name, grade_date_from
from cte as t1
where not exists (select 1 from cte t2
where t2.sol_last_name = t1.sol_last_name
and t2.grade_date_from < t2.grade_date_from)

Using group by with a sequence

I need to run an insert on folderrsn but my select is returning duplicates of folderrsns so i was trying to do a group by but I get the:
ORA-02287: SEQUENCE NUMBER NOT ALLOWED HERE
Is there a way to get around that or make my select statement more efficient?
INSERT INTO AMANDA.FOLDERFREEFORM(FREEFORMRSN, FREEFORMCODE, FOLDERRSN, C01, N01, N02, C02, C03, C04, D01, D02, D03, C05, C06)
SELECT AMANDA.FOLDERFREEFORMSEQ.NEXTVAL, 15030, F.FOLDERRSN, R.CATEGORY, R.REQUIRED, R.ELECTIVE, S.SCHOOL_NAME, C.CLASS_NAME, R.USED_FOR, R.DATE_USED, R.COURSE_DATE, RO.DATE_ROSTER_RECVD, R.CE_USED, I.INSTRUCTOR_NAME
FROM OREC_ROSTER_DTLS R
INNER JOIN AMANDA.FOLDER F ON F.CONVERSIONRSN = R.IND_SEQ_ID
INNER JOIN OREC_SCHOOLS S ON R.SCHOOL_NUMBER = S.SCHOOL_NUMBER
INNER JOIN OREC_COURSES C ON C.SCHOOL_NUMBER = S.SCHOOL_NUMBER
INNER JOIN OREC_ROSTERS RO ON R.ROSTER_NBR = RO.ROSTER_NBR
INNER JOIN OREC_INSTRUCTORS IS ON R.COURSE_INSTRUCTOR_NUMBER = IS.INSTRUCTOR_NUMBER
WHERE F.FOLDERTYPE = 'REAB'
Group by f.folderrsn;
This is your select query, without the sequence:
SELECT 15030, F.FOLDERRSN, R.CATEGORY, R.REQUIRED, R.ELECTIVE,
S.SCHOOL_NAME, C.CLASS_NAME, R.USED_FOR, R.DATE_USED, R.COURSE_DATE,
RO.DATE_ROSTER_RECVD, R.CE_USED, I.INSTRUCTOR_NAME
FROM OREC_ROSTER_DTLS R
INNER JOIN AMANDA.FOLDER F ON F.CONVERSIONRSN = R.IND_SEQ_ID
INNER JOIN OREC_SCHOOLS S ON R.SCHOOL_NUMBER = S.SCHOOL_NUMBER
INNER JOIN OREC_COURSES C ON C.SCHOOL_NUMBER = S.SCHOOL_NUMBER
INNER JOIN OREC_ROSTERS RO ON R.ROSTER_NBR = RO.ROSTER_NBR
INNER JOIN OREC_INSTRUCTORS IS ON R.COURSE_INSTRUCTOR_NUMBER = IS.INSTRUCTOR_NUMBER
WHERE F.FOLDERTYPE = 'REAB'
Group by f.folderrsn;
This is not correct, because the group by only has one column but the select has many others. I don't know what the intent of the group by is. However, if you had a working query, you can add the sequence using a subquery:
select AMANDA.FOLDERFREEFORMSEQ.NEXTVAL, t.*
from (select . . .
from . . .
group by . . .
) t

select query in subquery giving Column is invalid in the select list because it is not contained error

I have following query which i want to get sum counts for my data
SELECT
TI.[text] as zone,
YEAR (ER.Inserted) as [Year],
SUM(CONVERT(INT,DRT.RDRT)) as RDRT,
SUM(CONVERT(INT,DRT.FACT)) as FACT ,
SUM(CONVERT(INT,DRT.ERU)) as ERU,
(
SELECT COUNT(ER1.ReportID)
FROM dbo.EW_Reports ER1
INNER JOIN dbo.EW_Report_InformationManagement ERI ON ER1.ReportID = ERI.ReportID
INNER JOIN EW_Report_Country ERC1 ON ER1.ReportID = ERC1.ReportID
INNER JOIN ApplicationDB.dbo.Country C1 ON ERC1.CountryID = C1.countryId
INNER JOIN ApplicationDB.dbo.Region R1 ON C1.regionId = R1.regionId
INNER JOIN ApplicationDB.dbo.Zone Z1 ON R1.zoneId = Z1.zoneId
WHERE ERI.EmergencyAppeal IS NOT NULL
AND (YEAR ( ER1.Inserted) = YEAR ( ER.Inserted))
AND Z1.zoneId = Z.zoneId
) as emergencyAppeals
FROM EW_Reports ER
INNER JOIN EW_DisasterResponseTools DRT ON ER.ReportID = DRT.ReportID
INNER JOIN EW_Report_Country ERC ON ER.ReportID = ERC.ReportID
INNER JOIN ApplicationDB.dbo.Country C ON ERC.CountryID = c.countryId
INNER JOIN ApplicationDB.dbo.Region R ON c.regionId = R.regionId
INNER JOIN ApplicationDB.dbo.Zone Z ON R.zoneId = Z.zoneId
INNER JOIN ApplicationDB.dbo.Translation T ON Z.translationId = T.translationId
INNER JOIN ApplicationDB.dbo.TranslationItem TI ON T.translationId = TI.translationId
INNER JOIN EW_lofDisasterTypes D ON ER.DisasterTypeID = D.TranslationID AND D.LanguageID = 1 AND TI.languageID = 1
WHERE (YEAR ( ER.Inserted) IN (2011,2012))
GROUP BY TI.[text], YEAR (ER.Inserted)
But its giving following error
Column 'ApplicationDB.dbo.Zone.zoneId' is invalid in the select list
because it is not contained in either an aggregate function or the
GROUP BY clause.
Please assist me how to resolve this error .
there are too many ApplicationDB.dbo.Zone.zoneId records in your table already
simple add ApplicationDB.dbo.Zone.zoneId in group by then problem will solved
Select ....
.....
GROUP BY TI.[text], YEAR (ER.Inserted) ,ApplicationDB.dbo.Zone.zoneId
For your question why u need to add ApplicationDB.dbo.Zone.zoneId in my group as i am using that in ur subquery, this is because u perform a outer condition in your subquery
SELECT
----
(
SELECT
-----
INNER JOIN ApplicationDB.dbo.Zone Z1 ON R1.zoneId = Z1.zoneId
WHERE
----
AND Z1.zoneId = Z.zoneId
)
-----
INNER JOIN ApplicationDB.dbo.Zone Z ON R.zoneId = Z.zoneId
WHERE (YEAR ( ER.Inserted) IN (2011,2012))
------
note that you have a condition in different years
so your data flow may like this
ZoneID Years Record
1 2011 1000
1 2012 1000
same zone id contain different years, without proper grouping, sql got no way to group years column
it is showing the error because you have used this in sub query where condition
you need toadd ApplicationDB.dbo.Zone.zoneId in group by

Problems with joins and a query

Edit: Deleted my old message cause it was confusing. And i can't answer my own question for now.
Found, problem come from GROUP BY.
After some researches, i found that we can't use GROUP BY for group a column inside grouped rows.
So this work as expected :
SELECT candidats.*
, AVG(test_results.rate_good_answer) AS toto
FROM "candidats"
LEFT JOIN "sessiontests"
ON "sessiontests"."candidat_id" = "candidats"."id"
LEFT JOIN "test_results"
ON "test_results"."sessiontest_id" = "sessiontests"."id"
LEFT JOIN "questionnaires"
ON "questionnaires"."id" = "test_results"."questionnaire_id"
WHERE (sessiontests.terminate = 't' )
AND ("questionnaires"."category" LIKE '%java%' )
GROUP BY candidats.id
ORDER BY toto
But this will grouped only my column in test_results :
SELECT candidats.*,
FROM "candidats"
LEFT JOIN "sessiontests"
ON "sessiontests"."candidat_id" = "candidats"."id"
LEFT JOIN "test_results"
ON "test_results"."sessiontest_id" = "sessiontests"."id"
LEFT JOIN "questionnaires"
ON "questionnaires"."id" = "test_results"."questionnaire_id"
WHERE (sessiontests.terminate = 't' )
AND ("questionnaires"."category" LIKE '%java%' )
GROUP BY candidats.id, test_results.rate_good_answer
ORDER BY AVG(test_results.rate_good_answer)
Edit 3 :
My problem was the second query was returning each different test_results row for my candidats, whereas i expected it to return me one line per candidat.
First query, is the answer, and it works nice.
SELECT candidats.*
, AVG(test_results.rate_good_answer) AS toto
FROM "candidats"
LEFT JOIN "sessiontests"
ON "sessiontests"."candidat_id" = "candidats"."id"
LEFT JOIN "test_results"
ON "test_results"."sessiontest_id" = "sessiontests"."id"
LEFT JOIN "questionnaires"
ON "questionnaires"."id" = "test_results"."questionnaire_id"
WHERE (sessiontests.terminate = 't' )
AND ("questionnaires"."category" LIKE '%java%' )
GROUP BY candidats.id
ORDER BY toto