INNER JOIN Syntax Error - sql

I would like to JOIN 2 databases.
1 database is keyword_data (keyword mapping)
1 database is filled with Google rankings and other metrics
Somehow I cannot JOIN these two databases.
Some context:
DATA SET NAME: visibility
TABLE 1
keyword_data
VALUES
keyword
universe
category
search_volume
cpc
DATA SET NAME: visibility
TABLE 2
results
VALUES
Date
Keyword
Website
Position
In order to receive ranking data by date I wrote the following SQL line.
SELECT Date, Position, Website FROM `visibility.results` Keyword INNER
JOIN `visibility.keyword_data` keyword ON `visibility.results` Keyword
= `visibility.keyword_data` keyword GROUP BY Date;
(besides that, 100 other lines with no success ;-) )
I am using Google BigQuery for this with standard SQL (unchecked Legacy SQL).
How can I JOIN those 2 data tables?

How familiar are you with SQL? I think you're using aliases wrong, something like this should work
SELECT r.Date, r.Position, r.Website
FROM `visibility.results` AS r
INNER JOIN `visibility.keyword_data` AS k
ON r.Keyword = k.keyword
GROUP BY DATE

First of all i have never worked with Google big query but there is a couple of things wrong in my opinion with this query.
To start with you join tables by including the name of the table then you provide the key that the tables are joined by. Also if you don't use aggregate functions (MIN/MAX etc.) in your select statement you must include all values in the group by clause as well. In reference I can provide you a solution that would work if you would of used Microsoft SQL Server if that would be of any help because if you reference here the syntax is quite similar.
SELECT results.Date AS DATE,
,results.Position AS POSITION
,results.Website AS WEBSITE
FROM visibility.dbo.keyword_data AS keyword_data
INNER JOIN visibility.dbo.results AS results
ON results.keyword = keyword_data.keyword
GROUP BY results.Date
,results.Position
,results.Website

Related

Having troubles with a conditional count in SQL

I'm working on an SQL project (involving a library database) and I'm having a hard time figuring out how to make a conditional count.
So, I have 4 tables: Imprumuturi, Cititori, Autori, Carti. I need to list the 'Cititori' that have more than one borrowed 'Carti' at the current time.
I tried to use
SELECT cititori.nume_cititor,COUNT(imprumuturi.pk_cititor)
AS numar_imprumuturi FROM cititori, imprumuturi
WHERE imprumuturi.data_return IS NULL GROUP BY cititori.nume_cititor
HAVING COUNT(imprumuturi.pk_cititor)>1
ORDER BY cititori.nume_cititor;
And while it lists all the 'Cititori", it doesn't count the number of active borrowed 'Carti' as it should.
Can I get a hint or some help on how to make it work?
These are the fields of my database
Seems you missed the relation between the tables:
SELECT cititori.nume_cititor,COUNT(imprumuturi.pk_cititor)
AS numar_imprumuturi
FROM cititori
INNER JOIN imprumuturi ON imprumuturi.pk_cititori = cititori.pk_cititori
WHERE imprumuturi.data_return IS NULL
GROUP BY cititori.nume_cititor
HAVING COUNT(imprumuturi.pk_cititor)>1
ORDER BY cititori.nume_cititor;
As suggested, you should not use the old implicit join syntax based on comma-separated table names and where condition, but use explicit join syntax.

How can I write a SQL query to display ID, First Name, Last Name of all players with more than 2000 career hits based on schema

I am new to SQL and DB management. I am working on writing queries based on a schema which you can find below. This is an exercise for me to get familiar reading, writing queries on SQL Server for my job. Could you please help me out defining query based on the schema and simply explain the logic?
Thanks a lot!
SQL Server is my DBMS and here are the question
Display ID, First Name, Last Name, and Hits to display all players with more than 2000 career hits.
This one you can get by typing this query in Microsoft SQL Server
SELECT
MLB_PLAYERS.FIRST_NAME,
MLB_PLAYERS.LAST_NAME,
MLB_PLAYERS.ID,
CAREER_STATS.HITS
FROM
MLB_PLAYERS LEFT JOIN KEY_GAMES_STATS on MLB_PLAYERS.ID=CAREER_STATS.ID
WHERE
CAREER_STATS.HITS>2000
So you have a simple structure to follow:
SELECT
FROM
WHERE
GROUP BY
HAVING
ORDER BY
But you decide to get only 3 of them, which is select, from and where. By SELECT you decide which columns you wanna have as an output. Then in FROM you have to choose tables from which you wanna take your variables. But if you decide to use 2 different tables you need to join them. I used left join because I wanted to match hits to existing players. We can match them by similar key, in this case this is their ID. And eventually, you can use where to apply conditions to your queries
I guess you could do it with a join and a group
select p.MLB_PLAYERS.FIRST_NAME,
p.MLB_PLAYERS.LAST_NAME,
p.MLB_PLAYERS.ID,
count(g.KEY_GAMES_STATS.HITS) as hits
from MLB_PLAYERS p
left join KEY_GAMES_STATS on p.ID = g.ID -- not sure how to link there 2 tables
group by p.MLB_PLAYERS.FIRST_NAME,
p.MLB_PLAYERS.LAST_NAME,
p.MLB_PLAYERS.ID
having count(g.KEY_GAMES_STATS.HITS) > 2000

Question on getting number of day from single date column

Above is the screenshot of the tables for my practice. I want to extract the number of days between the earliest and latest sales made by staff 'Ali'. I do not have any SQL IDE to run the code and want to check any problem with my code.
SELECT DAYDIFF(day, MAX(st.Date), MIN(st.Date)) AS Duration
FROM SALES_TRANSACTION AS ST
LEFT JOIN SALES_MASTER AS sm
ON sm.Product_ID = st.Product_ID
GROUP BY sm.Staff_Name
HAVING sm.Staff_Name = 'Ali'
ORDER BY st.Date DESC
Here is the dataset
https://drive.google.com/file/d/13XCxQgbEONU22ZDYhQq-I1u-dh3A2fPc/view?usp=sharing
You want logic more like this:
SELECT DAYDIFF(day, MIN(st.Date), MAX(st.Date)) AS Duration
FROM SALES_TRANSACTION ST JOIN
STAFF_MASTER sm
ON sm.Staff_id = st.Staff_Id
WHERE sm.Staff_Name = 'Ali';
Note the changes:
The filtering is the in WHERE clause rather than the HAVING. In general, it is better to filter before aggregating if possible.
The LEFT JOIN is replaced by a JOIN. First, you need a match to get the name. Second, the foreign key reference should be valid so an outer join should not be necessary.
The correct table for the staff name is STAFF_MASTER.
If you are using SQL Server (which has the 3 argument DATEDIFF() syntax), then the smaller date is the second argument.
And finally, there are many tools on the web where you can test SQL, such as db<>fiddle, SQL Fiddle, and db-fiddle. You can also download free databases onto almost any platform.

Access SQL Syntax error: missing operator

I am trying to convert a T-SQL query to MS Access SQL and getting a syntax error that I am struggling to find. My MS Access SQL query looks like this:
INSERT INTO IndvRFM_PreSort (CustNum, IndvID, IndvRScore, IndRecency, IndvFreq, IndvMonVal )
SELECT
IndvMast.CustNum, IndvMast.IndvID, IndvMast.IndvRScore,
IndvMast.IndRecency, IndvMast.IndvFreq, IndvMast.IndvMonVal
FROM
IndvMast
INNER JOIN
OHdrMast ON IndvMast.IndvID = OHdrMast.IndvID
INNER JOIN
MyParameterSettings on 1=1].ProdClass
INNER JOIN
[SalesTerritoryFilter_Check all that apply] ON IndvMast.SalesTerr = [SalesTerritoryFilter_Check all that apply].SalesTerr
WHERE
(((OHdrMast.OrdDate) >= [MyParameterSettings].[RFM_StartDate]))
GROUP BY
IndvMast.CustNum, IndvMast.IndvID, IndvMast.IndvRScore,
IndvMast.IndRecency, IndvMast.IndvFreq, IndvMast.IndvMonVal,
[CustTypeFilter_Check all that apply].IncludeInRFM,
[ProductClassFilter_Check all that apply].IncludeInRFM,
[SourceCodeFilter_Check all that apply].IncludeInRFM,
IndvMast.FlgDontUse
I have reviewed differences between MS Access SQL and T-SQL at http://rogersaccessblog.blogspot.com/2013/05/what-are-differences-between-access-sql.html and a few other locations but with no luck.
All help is appreciated.
update: I have removed many lines trying to find the syntax error and I am still getting the same error when running just (which runs fine using T-SQL):
SELECT
IndvMast.CustNum, IndvMast.IndvID, IndvMast.IndvRScore,
IndvMast.IndRecency, IndvMast.IndvFreq, IndvMast.IndvMonVal
FROM
IndvMast
INNER JOIN
OHdrMast ON IndvMast.IndvID = OHdrMast.IndvID
INNER JOIN
[My Parameter Settings] ON 1 = 1
There are a number of items in your query that should also have failed in any SQL-compliant database:
You have fields from tables in GROUP BY not referenced in FROM or JOIN clauses.
Number of fields in SELECT query do not match number of fields in INSERT INTO clause.
The MyParameterSettings table is not properly joined with valid ON expression.
Strictly MS Access SQL items:
For more than one join, MS Access SQL requires paired parentheses but even this can get tricky if some tables are joined together and their paired result joins to outer where you get nested joins.
Expressions like ON 1=1 must be used in WHERE clause and for cross join tables as MyParameterSettings appears to be, use comma-separated tables.
For above reasons and more, it is advised for beginners to this SQL dialect to use the Query Design builder providing table diagrams and links (if you have the MS Access GUI .exe of course). Then, once all tables connect graphically with at least one field selected, jump into SQL view for any nuanced scripting logic.
Below is an adjustment to SQL statement to demonstrate the parentheses pairings and for best practices, uses table aliases especially with long table names.
INSERT INTO IndvRFM_PreSort (CustNum, IndvID, IndvRScore, IndRecency, IndvFreq, IndvMonVal)
SELECT
i.CustNum, i.IndvID, i.IndvRScore, i.IndRecency, i.IndvFreq, i.IndvMonVal
FROM
[MyParameterSettings] p, (IndvMast i
INNER JOIN
OHdrMast o ON i.IndvID = o.IndvID)
INNER JOIN
[SalesTerritoryFilter_Check all that apply] s ON i.SalesTerr = s.SalesTerr
WHERE
(o.OrdDate >= p.[RFM_StartDate])
GROUP BY
i.CustNum, i.IndvID, i.IndvRScore, i.IndRecency, i.IndvFreq, i.IndvMonVal
And in your smaller SQL subset, the last table does not need an ON 1=1 condition and may be redundant as well in SQL Server. Simply a comma separate table will suffice if you intend for cross join. The same is done in above example:
SELECT
IndvMast.CustNum, IndvMast.IndvID, IndvMast.IndvRScore,
IndvMast.IndRecency, IndvMast.IndvFreq, IndvMast.IndvMonVal
FROM
[My Parameter Settings], IndvMast
INNER JOIN
OHdrMast ON IndvMast.IndvID = OHdrMast.IndvID
I suppose there are some errors in your query, the first (more important).
Why do you use HAVING clause to add these conditions?
HAVING (((IndvMast.IndRecency)>(date()-7200))
AND (([CustTypeFilter_Check all that apply].IncludeInRFM)=1)
AND (([ProductClassFilter_Check all that apply].IncludeInRFM)=1)
AND (([SourceCodeFilter_Check all that apply].IncludeInRFM)=1)
AND ((IndvMast.FlgDontUse) Is Null))
HAVING usually used about conditions on aggregate functions (COUNT, SUM, MAX, MIN, AVG), for scalar value you must put in WHERE clause.
The second: You have 12 parenthesis opened and 11 closed in HAVING clause

Trouble with parenthesis in MS Access for SQL Inner Joins

Have tried the below SQL in MS Access but cannot seem to get it working, anyone got a better idea?
SELECT top 4 Student.STUDENT_DEGREE, Student.STUDENT_SEX,STUDENT_GROUP_ID,STUDENT_GROUP_ID2,RESULT_MARK
FROM (((Student)
INNER JOIN Result ON Student.STUDENT_ID=Result.RESULT_STUDENT_ID)
INNER JOIN Group ON RESULT_GROUP_ID = GROUP_ID)
where STUDENT_GROUP_ID <> ''
order by Result.RESULT_MARK desc;
Whenever i run this i just get the error:
Syntax error in FROM clause
Group is a reserved word. Enclose that name in square brackets to avoid confusing the db engine. You can also assign an alias for the table name.
FROM
(Student
INNER JOIN Result
ON Student.STUDENT_ID=Result.RESULT_STUDENT_ID)
INNER JOIN [Group] AS g
ON Result.RESULT_GROUP_ID = g.GROUP_ID
I had to guess which tables contain those fields in the last ON clause. If you set up the joins in Design View of the Access query designer, it will help you get the names right. It will also add the parentheses which the db engine requires for any query which includes more than one join.
Also qualify the table sources for the field names in your SELECT list and elsewhere in the query. Here again, the query designer can supply the correct names for you.
Remove the extra set of parentheses around Student:
SELECT top 4 Student.STUDENT_DEGREE,Student.STUDENT_SEX,STUDENT_GROUP_ID,STUDENT_GROUP_ID2,RESULT_MARK
FROM ((Student
INNER JOIN Result ON Student.STUDENT_ID=Result.RESULT_STUDENT_ID)
INNER JOIN Group ON RESULT_GROUP_ID = GROUP_ID)
where STUDENT_GROUP_ID <> ''
order by Result.RESULT_MARK desc;