Why is the following query a valid select ?
SELECT * from arelation somerandomtext;
The content of arelation does not matter, it just hast to be an existing view/table.
It returns the correct result, respectively the output of the select without the somerandomtext.
Why does this query do not throw an error/exception, is there no keyword (Group By, limit...) check ?
Its an alias
i.e.
select c.id, c.*
from products c
is valid syntax as it allows joins from a table to itself
i.e.
select c.id, p.id
from products c inner join products p on p.id = c.id
Related
I have a task in which I'm using Northwind database to select only these products which category name begins with 'C'. Product details are in table Products while CategoryName is in table Categories and this is the only answer I came up with
SELECT P.*
FROM Products P, Categories C
WHERE C.CategoryName LIKE 'C%' AND P.CategoryID = C.CategoryID
I was curious if I can do it without putting Categories inside FROM clause and connecting the tables. For me it seemed logical that I can access child table and use the values inside it smh, can you explain why it's not possible?
You can use a Correlated Subquery to achieve this:
SELECT *
FROM Products p
WHERE EXISTS (SELECT id FROM Categories c WHERE c.id = p.id)
This subquery is "Correlated" in that the SQL in the subquery references the query in which it's contained. Very similar to a join, but we are down in the WHERE clause using the EXISTS condition.
EXISTS is nice since it doesn't care what is returned by the subquery. It only cares that ANYTHING was returned by the subquery. So that subquery could also be: SELECT 1 FROM Categories WHERE c.id = p.id and this query would still work.
You should be using JOINS not that type of syntax (INNER, LEFT, RIGHT, ...)
But you can do this
SELECT P.*
FROM dbo.Products P WITH (NOLOCK)
INNER JOIN dbo.Categories C WITH (NOLOCK)
ON P.CategoryID = C.CategoryID
WHERE
SUBSTRING(LTRIM(C.CategoryName), 1, 1) = 'C'
Join Products with Categories using an INNER JOIN which will only return the records that match. Add WITH (NOLOCK) when selecting from a transactional database so it does not lock users when attempting to run a transaction. I try to avoid LIKE when possible so in your scenario you can use substring to get the first character. The first argument is the expression, then start index and then how many characters you need to grab. LTRIM will remove white spaces from the left so even if your CategoryName accidentally has a leading whitespace or spaces it will remove them before running the substring. RTRIM would be unnecessary for what you need
my query is like that:
SELECT o.id, o.title, oc.category_id,
(SELECT name from categories c where c.id = oc.category_id)
FROM objects o
LEFT JOIN object_categories oc ON oc.object_id = o.id
WHERE type_id = 17
it returns me table like at the image
I want to return non-repeating category name. Can anyone help me?
To do that you can use the DISTINCT ON expression:
https://www.postgresql.org/docs/9.0/sql-select.html#SQL-DISTINCT
In Postgres, you can use distinct on:
SELECT DISTINCT ON(c.id)
o.id,
o.title,
oc.category_id,
c.name,
count(*) over(partition by o.id) cnt
FROM objects o
LEFT JOIN object_categories oc ON oc.object_id = o.id
LEFT JOIN categories c ON c.c.id = oc.category_id
WHERE type_id = 17
ORDER BY c.id, o.id
When a category appears in than one record, this selects only the one that has the smallest object id.
I used the category id rather than the name to identify duplicates - you can use the category name instead, if that matters to you.
Note that I converted the inline subquery on categories to a regular join, since I find it more readable.
My sql query is returning distinct values.
This is the query:
select *
from Products
where [Product_ID] in (select Product_Id f
from MyCart
where User_Id = '5570928b-7a1b-4652-9c6b-592e76a70a07')
The second select query is returning (7,7,3) and the first select is returning information only for one 7 and 3.
I suppose it is because the 7's are duplicates, but I need the result to contain information about all the products in the second select, no matter if they are duplicate or not.
In that case, use JOIN:
select p.*
from Products p join
MyCart c
on p.Product_Id = c.Product_Id
where c.User_Id = '5570928b-7a1b-4652-9c6b-592e76a70a07';
Usually, duplicates are undesirable, which is why EXISTS and IN are used.
I want to map right column to left but i am getting error at select statement as Incorrect syntax near 'select'.Expecting ID
create table [AdventureWorks2014].[abc] as
select a.*,
b.*
from [Production].[Product] a
left join(
select distinct ProductID,Shelf
from [Production].[ProductInventory]
)b
on a.ProductID = b. ProductID;
Try using SELECT INTO:
select p.*, pi.shelf
into [AdventureWorks2014].[abc]
from [Production].[Product] p left join
(select distinct ProductID, Shelf
from [Production].[ProductInventory] pi
) pi
on p.ProductID = pi.ProductID;
Notes:
I am not aware that SQL Server supports CREATE TABLE AS.
The columns in a table need to have unique names. If you use *, you will get ProductId twice.
Abbreviations of the table names is the best naming conventions; meaningless letters such as a and b should be avoided.
Hi all I have a problem with an SQL query: the problem is that if i add GROUP BY the database engine outputs the error:
Column 'dbo.classes.class_name' is invalid in the select list because
it is not contained in either an aggregate function or the GROUP BY clause.
My query is:
string query = "SELECT p.*
FROM dbo.classes AS p INNER JOIN teacher_classes AS a
ON a.class_id = p.class_id
and teach_id = #id
GROUP BY p.class_id";
Is there any help please for that.
Note without group by the query work fine but the result not grouped.
Your query is:
SELECT p.*
FROM dbo.classes AS p INNER JOIN
teacher_classes AS a
ON a.class_id = p.class_id and teach_id = #id
GROUP BY p.class_name;
You are trying to select all the columns from p and yet you're are grouping by class_name. This is not allowed in most databases. What happens if you have two classes, but information is different from them?
One option is to use distinct rather than group by to remove duplicates:
SELECT distinct c.*
FROM dbo.classes c INNER JOIN
teacher_classes tc
ON tc.class_id = c.class_id and tc.teach_id = #id;
Another option is to use something like in to find the matching classes for the teacher:
select c.*
from classes c
where c.class_id in (select tc.class_id from teacher_classes where teach_id = #id)
Notice I also changed your aliases so they have some relationship to the table names. This makes the query much easier to read.