I am trying to do an inner join based on two columns and am having a problem referencing the columns correctly. I have used the following query which to the best of my knowledge is best pratice within postgresql. The two tables I am attempting to do an inner join on are mk_kw & adwords_final, both columns that are to be joined on are named "Key"
Here is the query
SELECT
*
FROM
adwords_final
INNER JOIN mk_kw ON "mk_kw.Key" = "adwords_final.Key";
Here is the result
ERROR: column "mk_kw.Key" does not exist
LINE 5: INNER JOIN mk_kw ON "mk_kw.Key" = "adwords_final.Key";
^
ERROR: column "mk_kw.Key" does not exist
SQL state: 42703
Character: 51
These columns certainly do exist within this context. Is there a better way to reference these columns?
Many Thanks.
The query should become:
SELECT
*
FROM
adwords_final
INNER JOIN mk_kw ON mk_kw.Key = adwords_final.Key;
Here is a sample of how to write inner joins:
SELECT Orders.OrderID, Customers.CustomerName
FROM Orders
INNER JOIN Customers ON Orders.CustomerID = Customers.CustomerID;
Orders and Customers are table names. CustomerID, CustomerName,OrderID are column names. All of them are case sensitive.
Peter Haddad's solution will still give you an error because key is a reserved word. You need to individually wrap the column name part of the query in double quotes as below:
SELECT
*
FROM
adwords_final
INNER JOIN
mk_kw ON mk_kw."Key" = adwords_final."Key";
Edit: Updated to reflect comments below
Related
I tried to do this in postgres why is not append?
SELECT
users.countries
FROM
users
INNER JOIN countries
ON countries.id = users.countries
ORDER BY countries;
You are using the join condition integer = array integer, it is not right. You must extract array elements after then you can use the joining condition. The best way for extracting array elements on PostgreSQL is to use unnest function. Also the performance of unnest is high. Examples:
-- Sample 1
select us.*, ct.country_name
from
users us
inner join
countries ct on ct.id in (select unnest(us.countries))
order by
us.countries;
-- Sample 2
select t_us.*, ct.country_name from
(
select us.username, us.first_name, us.last_name, unnest(us.countries) as country_id
from users us
) as t_us
inner join countries ct on ct.id = t_us.country_id
You need to use the ANY operator to compare a single value with an array of values:
SELECT users.countries, countries.*
FROM users
JOIN countries ON countries.id = ANY(users.countries)
ORDER BY countries;
I do not recommend modeling one-to-many (or actually many-to-many) relationships with arrays. It's better (=more efficient, more robust) to do that with a "classic" mapping table between users and countries.
I'm relatively new to derived tables when querying in From/Join clause as I always thought that Joins would eliminate the need for these subqueries. However, my question is that when I write a subquery within an inner join, do I need to specify the Joining column field within the subquery select statement to initiate a Join? I know you don't usually have to do this in a normal Join, however I wrote some sql code that won't execute unless I specify the joining column in the subquery select statement (I've bolded this). I've pasted the code below.
select pc.category_name
,product_name
,pp.list_price
,avg(quantity * (oi.list_price * (1-discount))) as Average_Revenue
,sum(quantity) as [products sold]
,sum(quantity * (oi.list_price * (1-discount))) as Revenue
,dt.Average_Category_Revenue
from production.categories as pc
inner join production.products as pp
on pc.category_id = pp.category_id
inner join sales.order_items as oi
on pp.product_id = oi.product_id
inner join (
select
category_name
,**pcc.category_id**
,avg(quantity * (oii.list_price * (1-discount))) as Average_Category_Revenue
from production.categories as pcc
inner join production.products as ppp
on pcc.category_id = ppp.category_id
inner join sales.order_items as oii
on ppp.product_id = oii.product_id
group by category_name, pcc.category_id
) as dt
on pp.category_id = dt.category_id
group by pc.category_name, product_name, pp.list_price, dt.Average_Category_Revenue
order by sum(quantity * (oi.list_price * (1-discount))) DESC
I have a many to many relation with three columns, (owner_id,property_id,ownership_perc) and for this table applies (many owners have many properties).
So I would like to find all the owner_id who has many properties (property_id) and connect them with other three tables (Table 1,3,4) in order to get further information for the requested result.
All the tables that I'm using are
Table 1: owner (id_owner,name)
Table 2: owner_property (owner_id,property_id,ownership_perc)
Table 3: property(id_property,building_id)
Table 4: building(id_building,address,region)
So, when I'm trying it like this, the query runs but it returns empty.
SELECT address,region,name
FROM owner_property
JOIN property ON owner_property.property_id = property.id_property
JOIN owner ON owner.id_owner = owner_property.owner_id
JOIN building ON property.building_id=building.id_building
GROUP BY owner_id,address,region,name
HAVING count(owner_id) > 1
ORDER BY owner_id;
Only when I'm trying the code below, it returns the owner_id who has many properties (see image below) but without joining it with the other three tables:
SELECT a.*
FROM owner_property a
JOIN (SELECT owner_id, COUNT(owner_id)
FROM owner_property
GROUP BY owner_id
HAVING COUNT(owner_id)>1) b
ON a.owner_id = b.owner_id
ORDER BY a.owner_id,property_id ASC;
So, is there any suggestion on what I'm doing wrong when I'm joining the tables? Thank you!
This query:
SELECT owner_id
FROM owner_property
GROUP BY owner_id
HAVING COUNT(property_id) > 1
returns all the owner_ids with more than 1 property_ids.
If there is a case of duplicates in the combination of owner_id and property_id then instead of COUNT(property_id) use COUNT(DISTINCT property_id) in the HAVING clause.
So join it to the other tables:
SELECT b.address, b.region, o.name
FROM (
SELECT owner_id
FROM owner_property
GROUP BY owner_id
HAVING COUNT(property_id) > 1
) t
INNER JOIN owner_property op ON op.owner_id = t.owner_id
INNER JOIN property p ON op.property_id = p.id_property
INNER JOIN owner o ON o.id_owner = op.owner_id
INNER JOIN building b ON p.building_id = b.id_building
ORDER BY op.owner_id, op.property_id ASC;
Always qualify the column names with the table name/alias.
You can try to use a correlated subquery that counts the ownerships with EXISTS in the WHERE clause.
SELECT b1.address,
b1.region,
o1.name
FROM owner_property op1
INNER JOIN owner o1
ON o1.id_owner = op1.owner_id
INNER JOIN property p1
ON p1.id_property = op1.property_id
INNER JOIN building b1
ON b1.id_building = p1.building_id
WHERE EXISTS (SELECT ''
FROM owner_property op2
WHERE op2.owner_id = op1.owner_id
HAVING count(*) > 1);
I am newbie in postgres. I have a query
SELECT * FROM orders
LEFT OUTER JOIN order_details ON order_details.orderid= orders.orderid
an it get error
SQL error:
ERROR: column order_details.orderid doesn't exist
LINE 2: LEFT OUTER JOIN order_details ON order_details.orderid...
^
In statement:
SELECT COUNT(*) AS total FROM (SELECT * FROM orders
LEFT OUTER JOIN order_details ON order_details.orderid= orders.orderid) AS sub
What am i missing in my query?
Thanks before
Postgres is case sensitive. Your SQL statement must be in the correct case, and if the table name or column name is not lower case then you must enclose it in double quotation marks. (as shown below)
SELECT * FROM orders
LEFT OUTER JOIN order_details ON order_details."OrderID"= orders.orderid
I have a stored procedure which is running quite slow. Therefore I want to extract some of the query in a separate view.
My code looks something like this:
DECLARE #tmpTable TABLE(..)
INSERT INTO #tmpTable (..) *query* (returns 3000 rows)
Select ... from table1
inner join table2
inner join table3
inner join #tmpTable
...
I then extract (copy-paste) the *query* and put it in a view - i.e. vView.
Doing this will then give me a different result:
Select ... from table1
inner join table2
inner join table3
inner join vView
...
Why? I can see that the vView and the #tmpTable both returns 3000 rows, so they should match (also did a except query to check).
Any comments would be much appriciated as I feel quite stuck with this..
EDITED:
This is the full query for getting the result (using #tmpTable or vView gives me different results, although the appear the same):
select dep.sid as depsid, dep.[name], COUNT(b.sid) as possiblelogins, count(ls.clientsid) as logins
from department dep
inner join relationship r on dep.sid=r.primarysid and r.relationshiptypeid=27 and r.validto is null
inner join [user] u on r.secondarysid=u.sid
inner join relationship r2 on u.sid=r2.secondarysid and r2.validto is null and r2.relationshiptypeid in (1,37)
inner join client c on r2.primarysid=c.sid
inner join ***#tmpTable or vView*** b on b.sid = c.sid
left outer join (select distinct clientsid from logonstatistics) as ls on b.sid=ls.clientsid
GROUP BY dep.sid, dep.[name],dep.isdepartment
HAVING dep.isdepartment=1
You maybe don't need the view/table if you change to this.
It joins on to client c and appears to be there only to JOIN onto logonstatistics
--remove inner join ***#tmpTable or vView*** b on b.sid = c.sid
--change JOIN
left outer join (select distinct clientsid from logonstatistics) as ls on c.sid=ls.clientsid
And change COUNT(b.sid) to COUNT(c.sid) in the SELECT clause
Otherwise, if you get different results you have two options I can see:
Table and view have different data. Have you run a line by line comparsion?
One has NULL, one has a value (especially for the sid column which will affect the JOIN)
Finally, when you says "different results" do you mean you get x2 or x3 rows? A different COUNT? What?