SQL Join and filter even further - sql

I need to add a condition that only selects the rows where a field (my_galleries.format) equals a string value of 'pictures'. I am trying to add it to this working sql statement.
SELECT
gallery_url,
preview_url
FROM
my_galleries,
my_gallery_previews
WHERE
my_galleries.gallery_id = my_gallery_previews.gallery_id
I tried this, with no luck....
SELECT
gallery_url,
preview_url
FROM
my_galleries,
my_gallery_previews
WHERE
my_galleries.gallery_id = my_gallery_previews.gallery_id
AND my_galleries.format='pictures'
Any ideas?

I recommend not using the FROM foo, bar WHERE foo.key = bar.key approach to performing a JOIN as it isn't very flexible and isn't obvious to new readers of your code. Instead you should perform an explicit JOIN instead:
SELECT
gallery_url,
preview_url
FROM
my_gallery_previews
INNER JOIN my_galleries ON my_gallery_previews.gallery_id = my_galleries.gallery_id
WHERE
my_galleries.format = 'pictures'

How about you try this
SELECT gallery_url, preview_url FROM my_galleries
JOIN my_gallery_previews ON
my_galleries.gallery_id = my_gallery_previews.gallery_id
WHERE my_galleries.format='pictures'
With the join, make sure to prefix your selected columns with their respective tables. I hope this helps

As others have stated I recommend you use the new structure of joining as it is more readable.
SELECT mg.gallery_url,
mgp.preview_url
FROM my_galleries mg
JOIN my_gallery_previews mgp ON mg.gallery_id = mgp.gallery_id
AND mg.format = 'pictures'
You can place the filter condition in the join using an AND statement. (Just another way to do it)
Your query appears to be correct syntax. I would recommend going through your data set or editing it into your question. It is possible that no picture gallery previews currently share a gallery id with an existing gallery row which is stopping the join from functioning.

Related

MS Access SQL sub Query using outer query result

I'm attempting to run a sub query based on the result of an outer query. The issue that I am having is that instead of using the outer query, I get a prompt for a value from the subquery.
SELECT Facilities.CustomerName, Facilities.FacilityName,
Facilities.AnnualPlan, Facilities.AppCo1,
(SELECT YeildDB.CornYield
FROM YeildDB
WHERE Facilites.AppCo1 = YeildDB.FIPS) AS Expr1
FROM Facilities
The goal is that the sub query should use the value from Facilities.AppCo1 to match with the value in YeildDB.FIPS and then return the corresponding value in YeildDB.CornYeild.
Currently I get a prompt asking for the YeildDB.FIPS value instead of the sub query using the outer query value.
Your code should work. But you can also express this using a LEFT JOIN:
SELECT Facilities.CustomerName, Facilities.FacilityName,
Facilities.AnnualPlan, Facilities.AppCo1,
YeildDB.CornYield
FROM Facilities LEFT JOIN
YeildDB
ON Facilties.AppCo1 = YeildDB.FIPS;
I noticed that you misspelled Facilities -- and that is probably why your version doesn't work. This is one reason to use table aliases:
SELECT f.CustomerName, f.FacilityName,
f.AnnualPlan, f.AppCo1,
y.CornYield
FROM Facilities as f LEFT JOIN
YeildDB as y
ON f.AppCo1 = y.FIPS;
Your sub query may be returning multiple values, hence the prompt asking you to specify which one you want. You can fix this (or at least hide this issue) by specifying top 1:
SELECT Facilities.CustomerName, Facilities.FacilityName,
Facilities.AnnualPlan, Facilities.AppCo1,
(SELECT TOP 1 YeildDB.CornYield
FROM YeildDB
WHERE Facilites.AppCo1 = YeildDB.FIPS) AS Expr1
FROM Facilities

MS Access SQL Update with Minimum

This SQL is beyond my expertise. I think it should be fairly easy for someone with experience. Here is what I have so far..
SQL is as follows:
UPDATE (Tbl_Stg_Project_Schedule_Dates
INNER JOIN Tbl_Child_ITN ON Tbl_Stg_Project_Schedule_Dates.ms_itn = Tbl_Child_ITN.ITN)
INNER JOIN Tbl_Schedule ON Tbl_Child_ITN.Id = Tbl_Schedule.ID SET Tbl_Schedule.a_construction_start = [Tbl_Stg_Project_Schedule_Dates].[ms_start_date]
WHERE (((Tbl_Stg_Project_Schedule_Dates.ms_tempt_id) In (16,17,18,19,20,21,22,23)));
I want to add one last condition to this being that I only want the minimum of [Tbl_Stg_Project_Schedule_Dates].[ms_start_date] to update the table. I've tried the obvious of wrapping the field in Min, and also tried creating a separate aggregate select statement first (to get the min value with other criteria) that I then tried to create the update query from in new query but no luck.
I believe this is valid Access/Jet SQL. The idea here is to use a subquery to look up the earliest date among all the rows in your subset. I'm not sure if ms_itn was the right column to correlate on but hopefully you get the idea:
UPDATE (Tbl_Stg_Project_Schedule_Dates
INNER JOIN Tbl_Child_ITN ON Tbl_Stg_Project_Schedule_Dates.ms_itn = Tbl_Child_ITN.ITN)
INNER JOIN Tbl_Schedule ON Tbl_Child_ITN.Id = Tbl_Schedule.ID
SET Tbl_Schedule.a_construction_start = [Tbl_Stg_Project_Schedule_Dates].[ms_start_date]
WHERE (((Tbl_Stg_Project_Schedule_Dates.ms_tempt_id) In (16,17,18,19,20,21,22,23)))
and [Tbl_Stg_Project_Schedule_Dates].[ms_start_date] = (
select min(sd.[ms_start_date])
from [Tbl_Stg_Project_Schedule_Dates] as sd
where sd.ms_itn = [Tbl_Stg_Project_Schedule_Dates].ms_itn
)

Nhibernate join filtering

I have a question about joins in NHIBERNATE. We had an issue with our sql query that was generated but nhibernate. Our db developer optimized the raw sql so it works as we need, but we need to change the nhibernate code to make generated sql look like optimized.
the part of the original part of the query is:
FROM PERSON_VISIT this_
inner join PERSON_Basic per2_
on this_.PERSON_ID = per2_.PERSON_ID
left outer join PERSONC_QUESTIONS perint10_
on per2_.PERSON_ID = perint10_.PERSON_ID
left outer join TELEPHONE_QUESTIONS intaudit13_
on perint10_.PP_QUESTIONS_ID = intaudit13_.PP_QUESTIONS_ID
inner join C_QUESTIONS intdef14_
on perint10_.QUESTION_ID = intdef14_.QUESTION_ID
and perint10_.QUESTIONS_CODE = intdef14_.QUESTIONS_CODE
and perint10_.QUESTION_ID = intdef14_.QUESTION_ID
The optimized one is :
FROM PERSON_VISIT this_
inner join PERSON_Basic per2_
on this_.PERSON_ID = per2_.PERSON_ID
left outer join PERSONC_QUESTIONS perint10_
on per2_.PERSON_ID = perint10_.PERSON_ID
left outer join TELEPHONE_QUESTIONS intaudit13_
on perint10_.PP_QUESTIONS_ID = intaudit13_.PP_QUESTIONS_ID
left outer join C_QUESTIONS intdef14_
on perint10_.QUESTION_ID = intdef14_.QUESTION_ID
and perint10_.QUESTIONS_CODE = intdef14_.QUESTIONS_CODE
and perint10_.QUESTION_ID = intdef14_.QUESTION_ID
and intdef14_.DISCIPLINE_CODE = this_.DISCIPLINE_CODE
To change query from inner join to left outer join is easy, i changed only one line of code:
.CreateAlias("PersonInt.QuestionEntity", "IntDef", JoinType.LeftOuterJoin)
But how I can add
and intdef14_.DISCIPLINE_CODE = this_.DISCIPLINE_CODE
using nhibernate code?
There is an option to add reference from PERSON_VISIT definition to C_QUESTIONS, but the problem is that
PERSON_VISIT is used everywhere and I don't want this change to possibly break other queries, I just wnat to add only one line of code to add, how I can do that? Is there any way to have access to the raw join to change it? Or some other way to add this
and intdef14_.DISCIPLINE_CODE = this_.DISCIPLINE_CODE
To the query?
I know that somebody will say that we can add a restriction to the query through criteria.Add, but it is not an option cause db developer optimized our query taking this restriction from WHERE clause to the join.
How I can do that quickly without changing the models definitions? Just changing only this one query without changing the whole model?
It is possible using HQL and the Criteria API's.
This question gives you the answer: Adding conditionals to outer joins with nhibernate
Something like this may solve your issue.
.CreateAlias("PersonInt.QuestionEntity", "IntDef", JoinType.LeftOuterJoin,
Restrictions.EqProperty("DISCIPLINE_CODE", "IntDef.DISCIPLINE_CODE"))
Thanks for answers. We use 2.0 version of NHibernate in our project so we didn't have a chance to use new methods of .CreateAlias with restrictions.
I have fixed an issue using Interceptors:
public class SqlInterceptor : EmptyInterceptor, IInterceptor
{
SqlString IInterceptor.OnPrepareStatement(SqlString sql)
{
//manipulating with the sql
return sql;
}
}
than
var factory = Session.SessionFactory;
var session = factory.OpenSession(new SqlInterceptor());
And use my query without a change.

sql query question inner join

LEFT JOIN PatientClinics AB ON PPhy.PatientID = AB.PatientID
JOIN Clinics CL ON CL.ID = AB.ClinicID
AND COUNT(AB.ClinicID) = 1
I get error using Count(AB.ClinicID) = 1 (ClinicID has duplicate values in the table and
I want to use only 1 value of each duplicate value of ClinicId to produce result)
What mistake am I making?
I've never seen a COUNT() being used in a JOIN before. Maybe you should use:
HAVING COUNT(AB.ClinicID) = 1
instead.
Count() can't be used as a join/filter predicate. It can be used in the HAVING clause however. You should include the entire query in order to get a better example of how to rewrite it.
maybe investigate the HAVING clause instead of using COUNT where you put it.
hard to help without the full query.

Trying to use table aliases in SQL

I'm a graphic designer trying my best to understand table aliases, but it's not working.
Here's what I have so far:
SELECT colours.colourid AS colourid1,
combinations.manufacturercolourid AS colourmanid1,
colours.colourname AS colourname1,
colours.colourhex AS colourhex1,
combinations.qecolourid2 AS colouridqe2,
colours.colourid AS colourid2,
colours.colourname AS colourname2,
colours.colourhex AS colourhex2,
colours.colourid AS colourid3,
combinations.qecolourid3 AS colouridqe3,
colours.colourname AS colourname3,
colours.colourhex AS colourhex3,
colours.colourid AS colourid4,
combinations.qecolourid4 AS colouridqe4,
colours.colourname AS colourname4,
colours.colourhex AS colourhex4,
combinations.coloursupplierid
FROM combinations
INNER JOIN colours
ON colours.colourid = combinations.manufacturercolourid;
Now, the idea is that in the colours lookup table, the id will pull the colour code, hex and name from the lookup table so that I can pull the colour code, hex and name for the 4 colours that I'm looking for. I can get this to work, but it only pulls up the first name, code and hex and I'm just not seeing what I'm doing wrong.
Your problem is that you are linking in only a single record from the colours table because you only have a single JOIN in your SQL. That record will match the color specified by manufacturer_colour_id.
You may also have a further problem in that your combinations table does not appear to be in proper normal form (although I could be wrong, not knowing the actual nature of the data you're trying to represent).
If I understand your problem correctly, the solution (using your current table structures) will be something more like:
SELECT C1.colourid AS colourid1,
CMB.manufacturercolourid AS colourmanid1,
C1.colourname AS colourname1,
C1.colourhex AS colourhex1,
CMB.qecolourid2 AS colouridqe2,
C2.colourid AS colourid2,
C2.colourname AS colourname2,
C2.colourhex AS colourhex2,
C3.colourid AS colourid3,
CMB.qecolourid3 AS colouridqe3,
C3.colourname AS colourname3,
C3.colourhex AS colourhex3,
C4.colourid AS colourid4,
CMB.qecolourid4 AS colouridqe4,
C4.colourname AS colourname4,
C4.colourhex AS colourhex4,
CMB.coloursupplierid
FROM combinations CMB
LEFT OUTER JOIN colours C1
ON C1.colourid = CMB.manufacturercolourid
LEFT OUTER JOIN colours C2
ON C2.colourid = CMB.qecolourid2
LEFT OUTER JOIN colours C3
ON C3.colourid = CMB.qecolourid3
LEFT OUTER JOIN colours C4
ON C4.colourid = CMB.qecolourid4
What's happening here is that I'm linking the colours table four times, once for each of the colour_id fields in the combinations table. To do so, I need to alias the table name each time so that I know which of the four possible instances of colours to use in the list of returned columns. Also, I'm using OUTER JOINs in the event that one or more colour_id columns might be empty. If that happened with INNER JOINs, the entire row would drop out of the result set.
You can use table aliases to reduce the amount of typing needed - by adding something like this:
SELECT
cl.colourid AS colourid1,
cb.manufacturercolourid AS colourmanid1,
cl.colourname AS colourname1,
... and so on.....
FROM
combinations AS cb
INNER JOIN
colours AS cl ON cl.colourid = cb.manufacturercolourid;
By defining a table alias cb for your table combinations, you can use that shorter alias in your SELECT and other parts of your statement, instead of having to always spell out the entire table name.
But your problem really is in the JOIN - you're only joining once, yet you expect to get four results back....
What you need to do is something like this:
SELECT
col1.colourid AS colourid1,
cb.manufacturercolourid AS colourmanid1,
col1.colourname AS colourname1,
col1.colourhex AS colourhex1,
cb.qecolourid2 AS colouridqe2,
col2.colourid AS colourid2,
col2.colourname AS colourname2,
col2.colourhex AS colourhex2,
col2.colourid AS colourid3,
cb.qecolourid3 AS colouridqe3,
col3.colourname AS colourname3,
col3.colourhex AS colourhex3,
col3.colourid AS colourid4,
cb.qecolourid4 AS colouridqe4,
col4.colourname AS colourname4,
col4.colourhex AS colourhex4,
cb.coloursupplierid
FROM
combinations cb
INNER JOIN colours AS col1 ON col1.colourid = cb.manufacturercolourid
INNER JOIN colours AS col2 ON col2.colourid = cb.qecolourid2
INNER JOIN colours AS col3 ON col3.colourid = cb.qecolourid3
INNER JOIN colours AS col4 ON col4.colourid = cb.qecolourid4
This is not an exhaustive answer, but your problem has to do with your how you are using the JOINs. Table and column aliases do not affect the output result set.
You are selecting the same field names four times, and that is why you are getting strange results.
These are all great, but for some reason when I try to use them, I get an error in the page:
[Microsoft][ODBC Microsoft Access Driver] Syntax error (missing operator) in query expression
I think I understand how to use the table aliases now, but for some reason, even though I'm sure it should work, the page doesn't like it.