I am an extreme rookie when it comes to SQL and I am trying to self teach myself. I have a few questions regarding SQL and writing queries:
I've been given some examples of queries by a colleague and many of them have the field names beginning with either m. or t. or o.email (eg. m.email or t.email or o.email). What do the prefixes indicate?
I am attempting to write a JOIN query but keep receiving an error message saying: An expression of non-boolean type specified in a context where a condition is expected, near ')' What would cause this? Neither of the data extensions I am trying to join contain boonlean fields.
I've written it as:
SELECT DISTINCT email, status_type, status_value_text FROM ent.[Table 1] JOIN [Table 2] ON email
Again, I am extremely new, any help would be greatly appreciated!
The general form of an SQL SELECT query is:
SELECT (columns, expressions, aggregate functions)
FROM (data sources)
WHERE (filters on data sources)
GROUP BY (columns used to group the data, needed if you use aggregate functions)
HAVING (filters on data AFTER it's grouped)
About the FROM clause, if you use more than one data source (table or view), you should think how your data will be related:
A cross join returns the cartesian product of the tables involved.Example:
FROM foo, bar will return all the rows of table foo and all the rows from table bar, without any rule on how they are related.
An inner join returns only the data that fulfills a relation rule.
Example:
FROM foo INNER JOIN bar ON foo.aField = bar.aField (alternative: FROM foo JOIN bar ON foo.aField = b.aField) will return only the rows of foo and bar that fulfils the condition provided (the field aField in each table must match). Important: An INNER JOIN must have a boolean expression, i.e. the relation must either be true or false; most times it will be an equality relationship (=) but it can be anything that returns a TRUE/FALSE value (>, <, >=, etcetera).
An outer join returns the full data of one table and only the rows of the other table that match the relation rule (for any other non-matching row of the first table, the columns from the second table will have a NULL value).
There are two possible outer joins: LEFT JOIN will return all the rows from the table on the left of the relation rule, and only the matching rows of the right table of the relation. RIGHT JOIN does just the opposite.
Example:
FROM foo LEFT JOIN bar ON foo.aField = bar.aField
As it was the case with the INNER JOIN, the relation must have a boolean expression.
Now, as you've noticed, you need to tell the system from which field you're getting the data. That's the reason for the "prefixes": They are the table (or schema.database.table) names. If you want, you can use aliases on this table names (just as you can use aliases on fields):
Example: FROM foo AS f INNER JOIN bar AS b on f.aField = b.aField
The aliases used in the FROM clause must be used every time you use the field in the same SELECT query.
Now, talking explicitly about your query: The JOIN in your post is missing the relation rule: You're telling the database server that the tables are related, but you're not defining the relation rule. Wich fields must match? Complete the JOIN expression with the columns that must match between the tables.
What do the prefixes indicate?
If you look at the FROM clause of the example queries you are questioning, you should notice table aliases specified after the full table names. Aliases are used sometimes just to shorten the table names from needing to be fully spelled out, but most often they are needed to disambiguate between similarly named columns in more than one of the tables in the FROM.
SELECT
-- Get the email column from the table aliased
-- as `m` (table1)
m.email
FROM
-- table1 aliased as m
table1 AS m
-- table1 aliased as e
INNER JOIN table2 AS e ON....
Consider two related tables, table1 and table2. Both of them has a column called email. In the SELECT list, you may not specify merely email because the RDBMS won't know which one you want. Instead, you must qualify it with the table name. Since the tables were aliased as m, e in the FROM, you must use the alias in SELECT instead of the full table name.
MS SQL Server documentation on table aliases...
An expression of non-boolean type specified in a context where a condition is expected, near ')'
In your join's ON clause, you simply supplied the column name email, which we can assume is a common value relating the two tables. A join's ON clause expects a boolean expression wherein a true value doing a row-wise comparison between the tables results in a row being returned.
So the ON clause needs a boolean expression with two sides, or something returning TRUE. In your case, it is equality between the email columns
SELECT DISTINCT
-- Must qualify email since both tables have it
-- Using the full table name, or its alias if an alias
-- was provided in `FROM`.
[Table 1].email,
status_type,
status_value_text
FROM
ent.[Table 1]
-- Equality between email columns completes the join
JOIN [Table 2] ON [Table 1].email = [Table 2].email
The expression in ON can be anything which evaluates to TRUE. It need not be an exact match between column values, though an exact match is by far the most common use case. You could say for example ON 1 = 1, which is always true. The resultant rowset would match every row from [Table 1] to every row of [Table 2] (which is a cartesian product). It could also be ON 1 = 2 which is never true, and therefore basically pointless since it would never return rows.
Using a syntax similar to the ON email you attempted, some RDBMS systems support a USING() in place of ON, allowing you to specify the equal column instead of a boolean expression. You might therefore also express it as
FROM
ent.[Table 1]
JOIN [Table 2] USING (email)
See also What's the difference between ON and USING
The m. or t. are aliases for tables within your query (so you are probably using tables that begin with the letter m and t). The alias is specified after the table name in the FROM part of your query.
The syntax looks off for your JOIN. The query should probably look more similar to this:
SELECT DISTINCT t1.email, t1.status_type, t2.status_value_text
FROM
[Table 1] t1 JOIN [Table 2] t2 ON t1.email = t2.email
Check out this link to see more examples.http://www.w3schools.com/sql/sql_join.asp
Related
I need to create 1 table based on matching the records of two tables, lets call them table p and table c, in SQL Server. The manual way to do this in Excel is to match the Order Column in table p with the Order Column in table c. Once those are matched, you take the corresponding Batch Column in table c and match it with the Batch Column in table p. Once those are matched you then take that corresponding Order Column in table p and match it with table c again and thats the final item we want to pull. Any ideas?
It's hard to say for sure given the lack of table definitions, but it sounds as though you need to do two joins, once over to table c, then back again to table p, which you would alias in order to pull the right column value. Perhaps this will help you get started.
SELECT p1.Order
FROM p
INNER JOIN C
ON p.Order = c.Order
INNER JOIN p as p1
ON p1.brance = c.branch
So i have to do a cartesian product (or CROSS JOIN) between two tables. One problem is that both tables have a column with the name 'itemname'. My current case looks as follows:
select *
into #cartesian_temp
from xsale CROSS JOIN xitem
delete from #cartesian_temp where deptname='books' and itemcolor='bamboo'
select * from #cartesian_temp
so the error I get is:
Column names in each table must be unique. Column name 'itemname' in table '#cartesian_temp' is specified more than once
Anyone that can help me with my problem?
you can add alias for the columns like below.
select XS.itemname as saleitemname , XI.itemname as saleitemname2
into #cartesian_temp
from xsale XS CROSS JOIN xitem XI
This is one of the reasons why seasoned SQL pro's will ALWAYS advocate to give Tables an alias and to ALWAYS fully qualify every column name by using the alias. It's not just a cross join problem
Avoid this:
SELECT *
FROM
person
INNER JOIN
address
ON addressid = address.id -- Person.addressid
Sure, it'll work as long as the column names are all unique (it'll probably cause issues even now because person will have an I'd column and so will address) but it might stop working at any point in future if someone adds columns to either table with names that clash
Prefer this:
SELECT p.id as personid, a.id as addressid, p.name, a.zipcode
FROM
person p
INNER JOIN
address a
ON p.addressid = a.id
This is fully aliased (both tables have an alias) and we haven't used select *; weve fully qualified every column with a prefix using the table alias and we've aliased columns that have the same named (the ID columns) in each table so we can tel them apart. No one can add any columns to the db and cause this query to stop working
Aliasing Tables helps in another way; it lets us use the same table twice in a query. Suppose a person had a work address and a home address:
SELECT ...
FROM
person p
INNER JOIN
address awork
ON p.workaddressid = awork.id
INNER JOIN
address ahome
ON p.homeaddressid = ahome.id
This is impossible without aliasing. Always give aliases a sensible name (not a1, a2)
For your case, go like:
SELECT xs.itemname as xsitemname, xi.itemname as xiitemname, ...
FROM
xsale xs
CROSS JOIN
xitem xi
WHERE
xi.itemcolor = 'green'
This will be every green item crossed with every sale item
I have 2 tables and suppose having bulk of data
Table1 Table2
Id Name Address Id Table1Id Parents_Name Address
1 ABC 123ABC 1 1 DDD Xyz
. ... ...... . . ... ...
. ... ...... . . ... ...
Now if i want solution in below format
Id Name Parents_Name
1 ABC DDD
. ... ...
. ... ...
then which one will be best
Subquery or join
Joins and subqueries are both be used to query data from different tables and may even share the same query plan, but there are many differences between them. Knowing the differences and when to use either a join or subquery to search data from one or more tables is key to mastering SQL.
Joins and subqueries are both used to combine data from different tables into a single result. They share many similarities and differences.
Subqueries can be used to return either a scalar (single) value or a row set; whereas, joins are used to return rows.
A common use for a subquery may be to calculate a summary value for use in a query. For instance we can use a subquery to help us obtain all products have a greater than average product price.
SELECT ProductID,
Name,
ListPrice,
(SELECT AVG(ListPrice)
FROM Production.Product) AS AvgListPrice
FROM Production.Product
WHERE ListPrice > (SELECT AVG(ListPrice)
FROM Production.Product)
There are two subqueries in this SELECT statement. The first’s purpose is to display the average list price of all products, the second’s purpose is for filtering out products less than or equal to the average list price.
Subquery Free Video Offer
Here the subquery is returning a single value which is then used filter out products.
Notice how the subqueries are queries unto themselves. In this example you could paste the subquery, without the parenthesis, into a query window and run it.
Contrast this with a join whose main purpose of a join is to combine rows from one or more tables based on a match condition. For example we can use a join display product names and models.
Select Product.Name,
ProductModel.Name as ModelName
FROM Production.product
INNER JOIN Production.ProductModel
ON Product.ProductModelID = ProductModel.ProductModelID
In this statement we’re using an INNER JOIN to match rows from both the Product and ProductModel tables. Notice that the column ProducModel.Name is available for use throughout the query.
The combined row set is then available by the select statement for use to display, filter, or group by the columns.
This is different than the subquery. There the subquery returns a result, which is immediately used.
Note that join is an integral part of the select statement. It can not stand on its own as a subquery can.
A subquery is used to run a separate query from within the main query. In many cases the returned value is displayed as a column or used in a filter condition such as where or having clause. When a subquery incorporates a column from the main query it is said to be correlated. In this way a sub query is somewhat like a join in that values from two or more tables can be compared.
Joins are used in the FROM clause of the WHERE statement; however, you’ll find subqueries used in most clauses such as the:
SELECT List – here a subqueries used to return single values are used.
WHERE clause– depending on the conditional operator you’ll see single value or row based subqueries.
FROM clause– It is typical to see row based result subqueries used here.
HAVING clause – In my experience scalar (single value) subqueries are used here.
Though joins and subqueries have many differences, they can be used to solve similar problems. In fact just because you write a SQL statement as a subquery doesn’t mean the DBMS executes as such.
you can refer to this link for more details:-
http://www.essentialsql.com/what-is-the-difference-between-a-join-and-subquery/
Asuming you want an INNER JOIN:
SELECT t1.Id
,t1.Name
,t2.Parents_Name
FROM table1 t1
INNER JOIN table2 t2
ON t2.Table1Id = t1.Id
But you could also use an OUTER JOIN to always show rows from table1 and show the matching rows from table2.
SELECT t1.Id
,t1.Name
,t2.Parents_Name
FROM table1 t1
LEFT OUTER JOIN table2 t2
ON t2.Table1Id = t1.Id
You will want to use a join, which will almost certainly be much more efficient. A quick google with give you much more information than you need to learn about the different types of joins available and how to use them, such as https://blog.codinghorror.com/a-visual-explanation-of-sql-joins/
Please create an index on the id of Table1 and Table1Id of Table2 and use this query.
Select t1.Id,
t1.Name,
t2.Parents_Name
from Table1 t1
inner join
Table2 t2 on t1.id=t2.Table1Id
IMHO, Join should be preferred considering query performance. Squbquery will require IN operator that is always a pain with bulk data. However it also depends in your indexing. Better you check both.
I need this query to return two values from the REPORT table, SUBJECT and ID_NUM.
Subject is selected as normal, but ID_NUM should only be selected if the SECRET is set to N in table IMS.
I would normally do
join on REPORT.ID_NUM = IMS.IR_ID_NUM
But in the SELECT statement Im unsure how to do this during the SELECT part before I have specified the WHERE table.
SELECT SUBJECT,
--Check if secret before selecting values
--Secret column is in IMS table, value i want selected is in REPORT
CASE
WHEN (SECRET = 'N') THEN ID_NUM
ELSE 'SECRET' END
AS 'ID_NUM ',
FROM REPORT
INNER JOIN IMS ON ID_NUM = IR_ID_NUM
INNER JOIN IR_SUBJECT ON IR_ID_NUM = SUB_ID_NUM
The different clauses of a SQL statement are (logically) executed in a certain order:
SELECT ... // 5.
FROM ... // 1.
JOIN ... ON ...
WHERE ... // 2.
GROUP BY ... // 3.
HAVING ... // 4.
ORDER BY ... // 6.
Taking them in order:
All records are select FROM the tables, applying any joins ON conditions, and cross-joining tables separated by comma (,).
Records are filtered according to WHERE clause.
Records are GROUP'ed.
Grouped values are filtered according to HAVING clause.
Result values are SELECT'd. Columns from all tables listed in FROM clause are available, including JOIN tables.
Result rows are ORDER'ed. You can even order by a calculated result value.
So, your CASE expression in the SELECT clause can access both SECRET and ID_NUM without problem.
Note: It is recommended to always qualify column names when more than one table is given. It is required if column name is ambiguous (more than one table has column of same name), but you should do it even for non-ambiguous column names, as documentation for other people (and yourself) reading the SQL statement later.
I have two tables CountryMaster and StatesMaster. The fields are:
CountryMaster(CountryId, Name)
StateMaster(StateId, Name, CountryId)
The StateMaster.CountryId is a Foreign key. I want to get the Name of States from StateMaster as well as the Name of the Country to which that State belongs from CountryMaster.
I want this in one query.
How can i get this?
SELECT
s.Name AS StateName
, c.Name AS CountryName
FROM
dbo.StateMaster s
INNER JOIN
dbo.CountryMaster c
ON c.CountryId = s.CountryId
Join Fundamentals
By using joins, you can retrieve data from two or more tables based on
logical relationships between the tables. Joins indicate how Microsoft
SQL Server should use data from one table to select the rows in
another table.
A join condition defines the way two tables are related in a query by:
Specifying the column from each table to be used for the join. A
typical join condition specifies a foreign key from one table and its
associated key in the other table.
Specifying a logical operator (for example, = or <>,) to be used
in comparing values from the columns.
Inner joins can be specified in either the FROM or WHERE clauses.
Outer joins can be specified in the FROM clause only. The join
conditions combine with the WHERE and HAVING search conditions to
control the rows that are selected from the base tables referenced in
the FROM clause.