PostgreSQL joining multiple tables - sql

Hi guys I am trying to join tables here, I want to add table called Table2 so that students from that table are displayed too. The thing which is confusing is I already have joins in this query, so how should add another join so that students from that Table2 are displayed as well, without breaking the existing code . Also, there is no way I can check output
The ID varables are stsidno in stTable 1, sidno in Table2, scsidno in table schedprd
Here's the code:
String selS = "select distinct stdistrict,stschool,stsidno,"
+ " sname as name,stgrade,"
+ "S.recnum as recnum, S.stldate as stldate,scsec,sctea,sccor,scgrade,scclsprd,scgrdprd,"
+ "case when P.scchangestartdate is null then C.clstart else "
+ "P.scchangestartdate end as scchangestartdate, "
+ "case when S.stedate is null or S.stedate<C.clstart "
+ "then C.clstart else S.stedate end as stedate "
+ "from stTable1 as S join schedprd as P on "
+ "(scyear=styear and scdistrict=stdistrict and scschool=stschool "
+ "and stsidno=scsidno and (scsec is not null and scsec<>'')) "
+ "left outer join calendar as C on (C.clyear=S.styear and "
+ "C.cldistrict=S.stdistrict and C.clschool=S.stschool and C.cltype='10') "
+ "where styear=? and stdistrict=? ";

You could UNION Table1 and Table2 together in a Common Table Expression (CTE) and then reference the CTE instead of Table1 in your query, like below:
WITH CTE
AS
(
SELECT *
FROM Table1
UNION
SELECT *
FROM Table2
)
select distinct
stdistrict,
stschool,
stsidno,
sname as name,
stgrade,
S.recnum as recnum,
S.stldate as stldate,
scsec,
sctea,
sccor,
scgrade,
scclsprd,
scgrdprd,
case when P.scchangestartdate is null then C.clstart else P.scchangestartdate end as scchangestartdate,
case when S.stedate is null or S.stedate<C.clstart then C.clstart else S.stedate end as stedate
from CTE as S
join schedprd as P on (scyear=styear and scdistrict=stdistrict and scschool=stschool and stsidno=scsidno and (scsec is not null and scsec<>''))
left outer join calendar as C on (C.clyear=S.styear and C.cldistrict=S.stdistrict and C.clschool=S.stschool and C.cltype='10')
where styear=? and stdistrict=?;

Related

SQL query grammatical exception on converting recursive query to JPQL

This is a JPQl query created from the below mentioned SQL query:
SELECT * FROM NursingSectionHead head where head.secCode IN (" +
"WITH NUR_SECTIONS_SEC_CODE (secCode) " +
"AS (SELECT secCode " +
"FROM NursingSection " +
"WHERE secCode = (SELECT loc.nursingSecCode FROM LocationMast loc WHERE loc.id.locCode = :locCode) " +
"UNION ALL " +
"SELECT C1.secCode " +
"FROM NursingSection C1 " +
"INNER JOIN NUR_SECTIONS_SEC_CODE C2 ON C1.prevSec = C2.secCode)" +
"SELECT * FROM NUR_SECTIONS_SEC_CODE)
This is the SQL query:
select * from IR_TB_NUR_SEC_HEAD head where HEAD.SEC_CODE IN (
WITH NUR_SECTIONS_SEC_CODE (SEC_CODE)
AS (
SELECT SEC_CODE
FROM IR_TB_NUR_SECTIONS
WHERE SEC_CODE = (select LOC.NURSING_SEC_CODE from mst_tb_location_mast loc where LOC.LOC_CODE = 20023)
UNION ALL
SELECT C1.SEC_CODE
FROM IR_TB_NUR_SECTIONS C1
INNER JOIN NUR_SECTIONS_SEC_CODE C2 ON C1.PREV_SEC = C2.SEC_CODE
)
SELECT *
FROM NUR_SECTIONS_SEC_CODE)
When executing it returns the below error:
"org.springframework.dao.InvalidDataAccessResourceUsageException:
could not extract ResultSet; SQL [n/a]; nested exception is
org.hibernate.exception.SQLGrammarException: could not extract
ResultSet"
What can I do about the above exception, please?
The "WITH" clause you are using is known as Common Table Expression (CTE) .I am pretty sure CTE is not supported by JPQL because if it is supported , no one will specially develop a library for supporting CTE query but only for Hibernate.
But you can switch to do use native SQL which should always work provided that your query can really be executed successfully against the database that you are using.

Sql Joins on multiple table returning product of two columns

I am trying to generate a report on a sql server database in asp.net and I am getting the results of some columns as a product of two columns. Here is the code
comm.CommandText = "SELECT Count(Courses.CourseID) AS CourseCount, Count(Students.StudentID) AS StudentCount, Schools.Name, Schools.StartDate, Schools.SchoolFees " +
"FROM Schools" +
"LEFT JOIN Courses ON (Schools.SchoolID = Courses.SchoolID)" +
"LEFT JOIN Students ON (Schools.SchoolID = Students.SchoolID) " +
"WHERE Schools.Active = 1 " +
"GROUP BY Schools.Name, Schools.StartDate, Schools.SchoolFees";
When I run the code, the result displays, but the columns for "CourseCount" and "StudentCount" display a value that is a product of each individual column. "CourseCount" is normally 288 and "StudentCount" is 38 but when I run the code, both "CourseCount" and "StudentCount" display 10944 which is 38 x 288.
Anyway I can make them display the correct values?
Changing your code from using a count of all rows, to a count of distinct values only, should return the results you expect
comm.CommandText = "SELECT Count(DISTINCT Courses.CourseID) AS CourseCount, Count(DISTINCT Students.StudentID) AS StudentCount, Schools.Name, Schools.StartDate, Schools.SchoolFees " +
"FROM Schools" +
"LEFT JOIN Courses ON (Schools.SchoolID = Courses.SchoolID)" +
"LEFT JOIN Students ON (Schools.SchoolID = Students.SchoolID) " +
"WHERE Schools.Active = 1 " +
"GROUP BY Schools.Name, Schools.StartDate, Schools.SchoolFees";
The results being returned are technically correct, if all schools have courses, and all courses have students
As stated above, it is how you are using the COUNT (), You are asking it to count all, which is why it returns so many. Use count on just the two values you want counted.
This might perform better than the DISTINCT Count method..
comm.CommandText =
"SELECT cc.CourseCount, sc.StudentCount, Schools.Name, Schools.StartDate, Schools.SchoolFees " +
"FROM Schools" +
"OUTER APPLY (SELECT Count(Students.StudentID) StudentCount FROM Students WHERE Students.SchoolID = Schools.SchoolID) sc " +
"OUTER APPLY (SELECT Count(Courses.CourseID) CourseCount FROM Courses WHERE Courses.SchoolID = Schools.SchoolID) cc " +
"WHERE Schools.Active = 1 ";

sqlite query not getting all records if 1 table has missing data

I've got a very complex database with a lot of tables in SQLite. I'm trying to design a query that will report out a lot of data from those tables and also report out those sheep who may not have a record in one or more tables.
My query is:
SELECT sheep_table.sheep_id,
(SELECT tag_number FROM id_info_table WHERE official_id = "1" AND id_info_table.sheep_id = sheep_table.sheep_id AND (tag_date_off IS NULL or tag_date_off = '')) AS fedtag,
(SELECT tag_number FROM id_info_table WHERE tag_type = "4" AND id_info_table.sheep_id = sheep_table.sheep_id AND (tag_date_off IS NULL or tag_date_off = '')) AS farmtag,
(SELECT tag_number FROM id_info_table WHERE tag_type = "2" AND id_info_table.sheep_id = sheep_table.sheep_id AND (tag_date_off IS NULL or tag_date_off = '') and ( id_info_table.official_id is NULL or id_info_table.official_id = 0 )) AS eidtag,
sheep_table.sheep_name, codon171_table.codon171_alleles, sheep_ebv_table.usa_maternal_index, sheep_ebv_table.self_replacing_carcass_index, cluster_table.cluster_name, sheep_evaluation_table.id_evaluationid,
(sheep_table.birth_type +
sheep_table.codon171 +
sheep_evaluation_table.trait_score01 +
sheep_evaluation_table.trait_score02 +
sheep_evaluation_table.trait_score03 +
sheep_evaluation_table.trait_score04 +
sheep_evaluation_table.trait_score05 +
sheep_evaluation_table.trait_score06 +
sheep_evaluation_table.trait_score07 +
sheep_evaluation_table.trait_score08 +
sheep_evaluation_table.trait_score09 +
sheep_evaluation_table.trait_score10 +
(sheep_evaluation_table.trait_score11 / 10 )) as overall_score, sheep_evaluation_table.sheep_rank, sheep_evaluation_table.number_sheep_ranked,
sheep_table.alert01,
sheep_table.birth_date, sheep_sex_table.sex_abbrev, birth_type_table.birth_type,
sire_table.sheep_name as sire_name, dam_table.sheep_name as dam_name
FROM sheep_table
join codon171_table on sheep_table.codon171 = codon171_table.id_codon171id
join sheep_cluster_table on sheep_table.sheep_id = sheep_cluster_table.sheep_id
join cluster_table on cluster_table.id_clusternameid = sheep_cluster_table.which_cluster
join birth_type_table on sheep_table.birth_type = birth_type_table.id_birthtypeid
join sheep_sex_table on sheep_table.sex = sheep_sex_table.sex_sheepid
join sheep_table as sire_table on sheep_table.sire_id = sire_table.sheep_id
join sheep_table as dam_table on sheep_table.dam_id = dam_table.sheep_id
left outer join sheep_ebv_table on sheep_table.sheep_id = sheep_ebv_table.sheep_id
left outer join sheep_evaluation_table on sheep_table.sheep_id = sheep_evaluation_table.sheep_id
WHERE (sheep_table.remove_date IS NULL or sheep_table.remove_date is '' )
and (eval_date > "2014-10-03%" and eval_date < "2014-11%")
and sheep_ebv_table.ebv_date = "2014-11-01"
order by sheep_sex_table.sex_abbrev asc, cluster_name asc, self_replacing_carcass_index desc, usa_maternal_index desc, overall_score desc
If a given sheep does not have a record in the evaluation table or does not have a record in the EBV table no record is returned. I need all the current animals returned with all available data on them and just leave the fields for EBVs and evaluations null if they have no data.
I'm not understanding why I'm not getting them all since none of the sheep have all 3 ID types (federal, farm and EID) so there are nulls in those fields and I was expecting nulls in the evaluation sum and ebv fields as well.
Totally lost in what to do to fix it.
The problem would appear to be that you're using eval_date in the WHERE statement. I'm assuming that eval_date is in the sheep_evaluation_table, so when you use it in WHERE, it gets rid of any rows where eval_date is NULL, which it would be when you're using a LEFT OUTER JOIN and there's no matching record in sheep_evaluation_table.
Try putting the eval_date filter on the join instead, like this:
left outer join sheep_evaluation_table on sheep_table.sheep_id = sheep_evaluation_table.sheep_id
AND (eval_date > "2014-10-03%" and eval_date < "2014-11%")
WHERE (sheep_table.remove_date IS NULL or sheep_table.remove_date is '' )

Access Select Query to show the same field with a different criteria

I have a select query in Access 2010 which shows a 'Level Name' where the 'Period ID' is set to 1
How can i add another field to the query which also shows the Level Name where the Period ID is set to 2?
I would like them both to be next to each other in separate rows
For reference, my current query looks like:
SELECT
qryMaster.[First Name] & " " & qryMaster.[Last Name] AS ChildName,
qryMaster.LevelName
FROM
qryMaster
WHERE
(
(qryMaster.ClassID = [Forms]![frmViewRecords_subject]![cboClass])
AND
(qryMaster.SubjectID = [Forms]![frmViewRecords_subject]![cboSubject])
AND
(qryMaster.PeriodID = 1)
);
I have added a picture of how my current query looks like in a sub form. I would like a new Column next to september, but for a different period
A WHERE clause is always for all fields. So if you want two different WHERE clauses then you need two queries.
Otherwise try
AND (qryMaster.PeriodID In(1,2))
I know this thread was active five month ago, but I had the same problem, found this page with google. Asuming others will arrive here too, I'll post the two solutions that I found below.
SELECT t1.ChildName, t1.LevelName1, qryMaster.LevelName
FROM
((SELECT
qryMaster.[First Name] & " " & qryMaster.[Last Name] AS ChildName,
qryMaster.LevelName as LevelName1
FROM qryMaster
WHERE
(
(qryMaster.ClassID = [Forms]![frmViewRecords_subject]![cboClass])
AND
(qryMaster.SubjectID = [Forms]![frmViewRecords_subject]![cboSubject])
AND
(qryMaster.PeriodID = 1)
)) AS t1)
LEFT JOIN qryMaster
ON t1.ChildName = (qryMaster.[First Name] & " " & qryMaster.[Last Name])
WHERE (
(qryMaster.ClassID = [Forms]![frmViewRecords_subject]![cboClass])
AND
(qryMaster.SubjectID = [Forms]![frmViewRecords_subject]![cboSubject])
AND
(qryMaster.PeriodID = 2)
)
As I do not have your data I couldn't test the code for your data, therefore I am not sure whether the "ON" clause works like this. In my case I have some customer ID there.
And the second one:
SELECT t1.[First Name] & " " & t1.[Last Name] AS ChildName, t1.LevelName AS LevelName1, t2.levelName AS LevelName2
FROM qryMaster t1
INNER JOIN qryMaster t2 ON t1.Childname=(t2.[First Name] & " " & t2.[Last Name])
WHERE (
(t1.ClassID = [Forms]![frmViewRecords_subject]![cboClass]) AND
(t1.SubjectID = [Forms]![frmViewRecords_subject]![cboSubject]) AND
(t1.PeriodID = 1) AND
(t2.ClassID = [Forms]![frmViewRecords_subject]![cboClass]) AND
(t2.SubjectID = [Forms]![frmViewRecords_subject]![cboSubject]) AND
(t2.PeriodID = 2)
)

MS SQL Conditional Join

I have a SQL Query :
SELECT * FROM Customer c
LEFT JOIN Invoice I ON I.InvcNum = C.Cust_InvcNum
some thing changed and the join does not work because there is no consistency in the data in the 'Cust_InvcNum'. So now when it does not find the record for the join or if it is null it needs to check for another condition.
LEFT JOIN Invoice I ON I.InvcNum = (SELECT p.InvcPrefix FROM Prefix WHERE p.DealerID = I.DealrID ) + '-' + I.InvcNum
second join I do works but it is taking too long for it get me data. Is there any other way to do this.
Earlier it used to be
Join on I.InvcNum = C.Cust_InvcNum
both the columns has the same data like DlrCd-InvcNum i.e both the columns 1234-A789
but not it could match on the above data or now the column 'InvcNum' in invoice table
can be populated like Dlrd-InvcNum or InvcPrefix-InvcNum
So InvcNum = 1234-A789 but CustNum = I94-A789
so we need to check if the for InvoicePrefix-InvcNum
SELECT *
FROM Customer c
LEFT JOIN (
SELECT i.InvcNum, p.InvcPrefix + '-' + I.InvcNum AS pInvcNum
FROM Invoice i LEFT JOIN Prefix p ON i.DealrID = p.DealrID
) ip ON c.Cust_InvcNum = CASE WHEN c.Cust_InvcNum = ip.InvcNum
THEN ip.InvcNum
ELSE ip.pInvcNum END