R - How to pass date as a argument in the SQL query - sql

I tried this following query:
studentcal3 <- function(x,y)
{
i<- x
print(i)
j <- y
print(j)
demo1 <-sqldf("SELECT a.StudentName, (b.marks/a.marks) as difference from
(select Date, StudentName, marks from studenthistorydemo WHERE Date= i) as a
INNER JOIN (select Date, StudentName, marks from studenthistorydemo where
Date= j) as b on a.marks= i and b.marks= j WHERE a.marks = i and b.marks =
j and a.StudentName=b.StudentName")
}
And then called the function
studentcal3('2014-01-01','2014-01-02')
Error:- Error in rsqlite_send_query(conn#ptr, statement) : no such column: i
How to resolve this?
P.S - I'm new to R

How should the engine know, which parts are external variables? You must use string concatenation (Read about paste()). And be aware, that you have to pass your variables within single quotes and in a culture and language independant format!
studentcal3 <- function(x,y)
{
i<- x
print(i)
j <- y
print(j)
cmd <-paste("SELECT a.StudentName, (b.marks/a.marks) as difference from ",
"(select Date, StudentName, marks from studenthistorydemo WHERE Date='",i,"') as a ",
"INNER JOIN (select Date, StudentName, marks from studenthistorydemo where ",
"Date='",j,"') as b on a.marks='",i,"' and b.marks='",j,
"' WHERE a.marks ='",i,"' and b.marks ='",j,"' and a.StudentName=b.StudentName",sep="")
#demo1 <-sqldf(cmd)
print(cmd)
}
studentcal3('2014-01-01','2014-01-02')
The result
"SELECT a.StudentName, (b.marks/a.marks) as difference from (select
Date, StudentName, marks from studenthistorydemo WHERE
Date='2014-01-01') as a INNER JOIN (select Date, StudentName, marks
from studenthistorydemo where Date='2014-01-02') as b on
a.marks='2014-01-01' and b.marks='2014-01-02' WHERE a.marks
='2014-01-01' and b.marks ='2014-01-02' and a.StudentName=b.StudentName"
And be aware of sql injection! You might build a statment with real parameters to avoid injection attacks.
If this statement really delivers what you expect is another question. You might print it out and paste it into a query window to test it first...

Related

Need help for an exercise for school, and I cant figure out why doesn't SUM work here

SELECT
F.numero,
SUM (SELECT (C.unidades * P.preco)
FROM linhafatura C, produto P)
WHERE (C.produto = P.ean13)
AND (C.produto = L.produto)
AND (C.fatura = L.fatura))
FROM fatura F, linhafatura L
WHERE (F.numero = L.fatura);
I tested it in SQL live and it just says
ORA-00936: missing expression
which is a really helpful error
(I am sure the tables and data introduced are all correct because the code was made by my teachers)
Any help is accepted, thanks
Your query extra closing bracket after FROM linhafatura C, produto P) and you need to wrap the correlated sub-query inside () brackets so you have one set of brackets for the SUM() function and another for the sub-query and you also need a GROUP BY clause:
SELECT F.numero,
SUM(
(
SELECT (C.unidades * P.preco)
FROM linhafatura C, produto P
WHERE (C.produto = P.ean13)
AND (C.produto = L.produto)
AND (C.fatura = L.fatura)
)
) AS value
FROM fatura F,
linhafatura L
WHERE (F.numero = L.fatura)
GROUP BY
f.numero;
Which can be rewritten without the additional brackets as:
SELECT F.numero,
SUM(
(
SELECT C.unidades * P.preco
FROM linhafatura C, produto P
WHERE C.produto = P.ean13
AND C.produto = L.produto
AND C.fatura = L.fatura
)
) AS value
FROM fatura F,
linhafatura L
WHERE F.numero = L.fatura
GROUP BY
f.numero;
and again, rewritten with modern ANSI joins (rather than the legacy comma-join syntax from 30 years ago):
SELECT F.numero,
SUM (
(
SELECT C.unidades * P.preco
FROM linhafatura C
INNER JOIN produto P
ON C.produto = P.ean13
WHERE C.produto = L.produto
AND C.fatura = L.fatura
)
) AS value
FROM fatura F
INNER JOIN linhafatura L
ON F.numero = L.fatura
GROUP BY
f.numero;
fiddle
Note: depending on your data you may get the error: ORA-01427: single-row subquery returns more than one row fiddle

JPQL: Switch/case when an object does not exist on the database

I am writing an #Query for a repository method. This query should return all Movie which have an average Rating less than the given parameters value:
#Query(value =
"select m from Movie m " +
"where (select avg(r.rating) from Review r " +
"where m.id = r.movie.id) < :rating")
List<Movie> findMoviesWithAverageRatingLowerThan(#Param("rating") Double rating);
The problem is that I have a requirement that when a Movie has no ratings, it should be interpreted as an average rating equal 0.
I have a clue that I should use switch/case combined with when, but as for now I have no idea how to do it.
Is this even possible to achieve this in one query?
You can try to use COALESCE expression like below:
#Query(value =
"select m from Movie m " +
"where (select avg(COALESCE(r.rating, 0)) from Review r " +
"where m.id = r.movie.id) < :rating")
List<Movie> findMoviesWithAverageRatingLowerThan(#Param("rating") Double rating);

Continue to get duplicate results with SQL Query

I was thinking it might be an issue with the joins? I've tried Group by to no avail...
Any advice would be appreicated! I've placed the query below:
*Sorry for the lack of details- Med_Prof_Record_No is the unique value, and I know the code is messy- but this is what was here when I got here ;-) Also this is a sql 2000 box, so new syntax won't work... I've cleaned up the joins abit but don't want to stray too far from the original queries-
SELECT DISTINCT
P.Last_name + ', ' + P.First_name AS Full_name,
P.Degree,
F.Med_Prof_Record_No,
F.Current_status,
F.Status_category,
F.Department_name,
F.Section,
F.SPHAffiliatedPhysiciansSurgeons AS Affiliated,
S.Board_Name,
S.Specialty_Name,
O.Office_name,
O.Address_1,
O.Address_2,
O.City,
O.State,
O.Zip_Code,
O.Phone_number_1,
O.Fax_number
FROM
Med_Prof P, Med_Prof_Facilities F, Med_Prof_Specialties S, Med_Prof_Offices O
WHERE
(F.Med_Prof_Record_No = P.Med_Prof_Record_No) AND
(F.Med_Prof_Record_No = S.Med_Prof_Record_No) AND
(F.Med_Prof_Record_No = O.Med_Prof_Record_No) AND
<cfif URL.LastName is NOT "">(P.Last_name LIKE '#URL.LastName#%') AND</cfif>
<cfif URL.Specialty is NOT "">(F.Section = '#URL.Specialty#') AND</cfif>
<cfif URL.Group is NOT "">(O.Office_name LIKE '#URL.Group#%') AND</cfif>
(F.Status_category = 'active')
ORDER by Full_name
Here is a stab. This makes assumptions about how you want to decide which office etc. to show (in this case it is as good as arbitrary), that P.Med_Prof_Record_No is unique and only represents one person (at first I thought Last_name + First_name is unique, but that seems a very dangerous assumption), and also that you are using SQL Server 2005 or better. Finally, please use properly qualified object names and please, please, please stop using lazy implicit joins of the FROM foo, bar, blat, splunge variety.
;WITH x AS
(
SELECT
P.Last_name + ', ' + P.First_name AS Full_name,
P.Degree,
F.Med_Prof_Record_No,
-- other columns from F,
S.Board_Name,
S.Specialty_Name,
O.Office_name,
-- other columns from O,
rn = ROW_NUMBER() OVER (PARTITION BY P.Med_Prof_Record_No
ORDER BY F.Current_status, S.Board_name, O.Office_name)
FROM
dbo.Med_Prof AS P
INNER JOIN
dbo.Med_Prof_Facilities AS F
ON P.Med_Prof_Record_No = F.Med_Prof_Record_No
INNER JOIN
dbo.Med_Prof_Specialties AS S
ON F.Med_Prof_Record_No = S.Med_Prof_Record_No
INNER JOIN
dbo.Med_Prof_Offices AS O
ON F.Med_Prof_Record_No = O.Med_Prof_Record_No
WHERE
<cfif ... AND</cfif>
-- other <cfif> clauses
(F.Status_category = 'active')
)
SELECT * FROM x WHERE rn = 1
ORDER BY Full_name;

SQL on how to simultaneously compare two column values in a query

I need create a query to find the names of drivers whose exam scores get lower when they take more exams. So I have the following tables:
branch(branch_id, branch_name, branch_addr, branch_city, branch_phone);
driver(driver_ssn, driver_name, driver_addr, driver_city, driver_birthdate, driver_phone);
license(license_no, driver_ssn, license_type, license_class, license_expiry, issue_date, branch_id);
exam(driver_ssn, branch_id, exam_date, exam_type, exam_score);
**the exam_date is a date
So I am using the tables driver and exam. I would like to somehow check that the exam_date>anotherDate while at the same time checking that exam_score
*EDIT
This is what I came up with but I feel like some of the syntax is illegal. I keep getting a syntax error.
s.executeQuery("SELECT driver_name " +
"FROM driver " +
"WHERE driver.driver_ssn IN " +
"(SELECT e1.driver_ssn" +
"FROM exam e1" +
"WHERE e1.exam_score < " +
"(SELECT e2.exam_score FROM exam e2)" +
"AND e1.exam_date > " +
"(SELECT e2.exam_date FROM exam e2)");
EDIT! I got it working! Thanks for your input everyone!
SELECT driver.driver_name
FROM driver
WHERE driver.driver_ssn IN
(SELECT e1.driver_ssn
FROM exam e1, exam e2, driver d
WHERE e1.exam_score < e2.exam_score
AND e1.exam_date > e2.exam_date
AND e1.driver_ssn=e2.driver_ssn)
You will need to do a self join. See this example and work it to your schema.
select d.name,
es.date_taken as 'prev date',
es.score as 'prev score',
es.date_taken as 'new date',
es_newer.score as 'new score'
from driver d
inner join exam_score es
on d.id = es.driver_id
left outer join exam_score es_newer
on d.id = es_newer.driver_id
and es_newer.date_taken > es.date_taken
and es_newer.score < es.score
where es_newer.id is not null
Here is a SQL Fiddle that I made to demonstrate.
SELECT returns a set and you cannot compare a single value against a set. You can try something along these lines. This is similar to yours and doesn't handle three exam case :-
SELECT driver_name
FROM driver
JOIN exam e1 ON driver_ssn
JOIN exam e2 ON driver_ssn
WHERE e1.exam_score < e2.exam_score
AND e1.exam_date > e2.exam_date
The query selects all pairs of exams taken by a driver in which the score is less and the date big
Simple take on this problem would be getting drivers who take a couple of exams and their second score is lower.
To compare columns from the same table SQL uses self-join. Your join condition should include:
select e1.driver_ssn, e1.exam_type, e1.exam_score as score_before,
e2.exam_score as score_after
exam e1 join exam e2 on (e1.driver_ssn = e2.driver_ssn and
e1.exam_type = e2.exam_type and
e1.exam_date < e2.exam_date and
e1.exam_score > e2.exam_score)

incorrect syntax near the keyword 'AS'

Why do i receive a syntax error as such: Incorrect syntax near the keyword 'AS'
I am using microsoft visual studio 2005 and sql server 2005
string strSql =
"SELECT a.MCode, a.NameOfModule, a.Mod_Abbreviation, dt.ModuleCode,
dt.Course, dt.Stage, dt.ModuleGrpFrom, dt.ModuleGrpTo, dt.GrpName,
dt.GrpType, dt.StaffID, dt.AcadYear, dt.AcadSemester,
dt.TotalHour, dt.WeeklyLectHr, dt.WeeklyPractHr, dt.WeeklyTutHr,
dt.ModuleLeader, 0 AS TotalTeach, '' AS ModuleGroups, '' AS ML, 0 AS L, 0 AS P, 0 AS T, 1 AS NofGrp, '' AS TotalTeachUnit" +
"FROM (SELECT * FROM
(SELECT a.ModuleCode, a.Course, a.Stage, a.ModuleGrpFrom,
a.ModuleGrpTo, a.GrpName, a.GrpType, a.StaffID, b.AcadYear,
b.AcadSemester, b.TotalHour, b.WeeklyLectHr, b.WeeklyPractHr,
b.WeeklyTutHr, b.ModuleLeader
FROM ModuleStrGrp a
LEFT JOIN ModuleStr b ON a.AcadYear = b.AcadYear
AND a.AcadSemester = b.AcadSemester
AND a.Course = b.Course
AND a.ModuleCode = b.ModuleCode) AS MSG
INNER JOIN Parameter Para ON MSG.Course = Para.Paracode2) AS dt
LEFT JOIN Module a ON dt.ModuleCode = a.MCode" +
"WHERE dt.AcadYear LIKE AcadYear AND dt.AcadSemester LIKE AcadSemester
AND dt.Course LIKE Course AND dt.Stage LIKE Stage AND dt.StaffID LIKE Staff
AND dt.SpecGrp LIKE Specialisation" +
"ORDER BY dt.ModuleCode, dt.GrpType";
Missing spaces.
Your code is creating the string
"... , '' AS TotalTeachUnitFROM (SELECT * ..."
Same goes for the other lines, they need spaces between them.
I won't answer your question, but I'll give you a strategy:
copy the contents of the strSql string to the clipboard, then to a query in SQL Management Studio, and run it there.
Then it will actually tell you which "AS" is causing the problem. Most likely it's a missing space or appostraphe or comma.
make "FROM ... as " FROM ...
right now it is ... AS TotalTeachUnitFROM ...
You are missing spaces.
"...a ON dt.ModuleCode = a.MCode" +
"FROM (SELECT * FROM ..."
results in
"...a ON dt.ModuleCode = a.MCodeFROM (SELECT * FROM ..."
^
space missing
Rather use # instead of +
string strSql = #"SELECT a.MCode, a.NameOfModule, a.Mod_Abbreviation, dt.ModuleCode, dt.Course, dt.Stage, dt.ModuleGrpFrom, dt.ModuleGrpTo, dt.GrpName, dt.GrpType, dt.StaffID, dt.AcadYear, dt.AcadSemester, dt.TotalHour, dt.WeeklyLectHr, dt.WeeklyPractHr, dt.WeeklyTutHr, dt.ModuleLeader, 0 AS TotalTeach, '' AS ModuleGroups, '' AS ML, 0 AS L, 0 AS P, 0 AS T, 1 AS NofGrp, '' AS TotalTeachUnit
FROM (SELECT * FROM (SELECT a.ModuleCode, a.Course, a.Stage, a.ModuleGrpFrom, a.ModuleGrpTo, a.GrpName, a.GrpType, a.StaffID, b.AcadYear, b.AcadSemester, b.TotalHour, b.WeeklyLectHr, b.WeeklyPractHr, b.WeeklyTutHr, b.ModuleLeader FROM ModuleStrGrp a LEFT JOIN ModuleStr b ON a.AcadYear = b.AcadYear AND a.AcadSemester = b.AcadSemester AND a.Course = b.Course AND a.ModuleCode = b.ModuleCode) AS MSG INNER JOIN Parameter Para ON MSG.Course = Para.Paracode2) AS dt LEFT JOIN Module a ON dt.ModuleCode = a.MCode
WHERE dt.AcadYear LIKE AcadYear AND dt.AcadSemester LIKE AcadSemester AND dt.Course LIKE Course AND dt.Stage LIKE Stage AND dt.StaffID LIKE Staff AND dt.SpecGrp LIKE Specialisation
ORDER BY dt.ModuleCode, dt.GrpType";