SQL SELECT statement - sql

I need to make an sql SELECT statement where I will join tables(or get the value from joined table) only if condition is met, is this possible ?
I have an order table where I have user IDs, but I also have random generated IDs for users who ordered as guests. And I want to join users table on orders table, with that ID, but when the ID is randomly generated I want to return only values from order table because there are not records in user table for that ID.
I have only this, which will write rows where user_id exists in both tables
$sql = "SELECT orders.id_o, orders.user_id, orders.price, users.username
FROM orders JOIN users
ON orders.user_id = users.id
ORDER BY order_date ASC";

This is exactly what left joins are for. To answer the followup question in the comments, you can use coalesce to replace the nulls returned from the left join:
SELECT orders.id_o, orders.user_id, orders.price,
COALESCE(users.username, 'Guest')
FROM orders
LEFT JOIN users ON orders.user_id = users.id
ORDER BY order_date ASC

Nearly, just change to left join
$sql = "SELECT orders.id_o, orders.user_id,orders.price, users.username
FROM orders Left JOIN users
ON orders.user_id = users.id
ORDER BY order_date ASC";

The following statement should do it:
SELECT
orders.id_o,
orders.user_id,
orders.price,
users.username
FROM orders
LEFT JOIN users
ON orders.user_id = users.id
ORDER BY order_date ASC

Related

UPDATE with INNER JOIN on SQL Server

I have 2 tables Users and Orders. Primary key of Users is UserId, which I have defined as foreign key in the Orders table. I have added a new column of UserName to Orders. I want to import UserName from Users table.
I'm trying to run this code, but it keeps giving me errors. Can someone tell me what could be wrong?
UPDATE Orders
SET Orders.UserName = Users.UserName
INNER JOIN Users ON Orders.UserId = Users.UserId;
That's not the right syntax
UPDATE O
SET O.UserName = U.UserName
from Orders O
INNER JOIN Users U ON O.UserId = U.UserId ;
You need to start using Alias for tables references when there is more than one table involved in your query. Using Alias names makes the query more readable.
you are missing orders table name
UPDATE Orders
SET Orders.UserName = Users.UserName
from Orders
INNER JOIN Users ON Orders.UserId = Users.UserId ;
No UPDATE with INNER JOIN, please re-write your query as follow:
You can use INNER JOIN only after FROM clause
UPDATE Orders SET Orders.UserName = Users.UserName
FROM Users WHERE Orders.UserId = Users.UserId
I actually like the CTE version of the update here, because it lets us expression the join logic as we would in a select, without any potential confusion:
WITH cte AS (
SELECT o.UserName AS user_old, u.UserName AS user_new
FROM Orders o
INNER JOIN Users u ON u.UserId = o.UserId
)
UPDATE cte
SET user_old = user_new;
Your query structure should be like below :
UPDATE
t1
SET
t1.c1 = t2.c2,
t2.c2 = expression,
...
FROM
t1
[INNER | LEFT] JOIN t2 ON join_predicate
WHERE
where_predicate;
So your actual query should be like below :
UPDATE Orders SET Orders.UserName = Users.UserName
FROM Users WHERE Orders.UserId = Users.UserId

Query to find the max of a value with multiple group by attributes

I am trying to get the max bidamt on a particular item and display the user who has bid that amount
I am able to get the results in two different queries each returning a subset of what I want
select username, auctionbids.itemid, description, bidamt from AuctionBids
inner join users on auctionbids.userid = users.id
inner join auctionitems on auctionbids.itemid = auctionitems.itemid
select ab.itemid,max(ab.bidamt) as bidmax from auctionbids as ab group by ab.itemid
I want to get username, itemid, item descripton, max(bidamt) joining three tables - users, auctionitems, auctionbids.
users contains userid and username
auctionitems contains itemid and item description
auctionbids contains userid, itemid, bidamt
The following query should do what you want:
SELECT a.item_description,a.username,a.bidamt FROM
(
SELECT au.item_description,u.username,ab.bidamt, RANK() OVER(PARTITION BY au.itemid ORDER BY ISNULL(ab.bidamt,0) DESC) AS [Rank]
FROM auctionitems au
LEFT JOIN auctionbids ab ON au.itemid = ab.itemid
LEFT JOIN users u ON ab.userid = u.userid ) a WHERE [Rank] = 1
As you said, the two different queries each returning a subset of what you want, your query should like this:
SELECT am.username, am.itemid, am.descripton, max(am.bidamt) AS bidmax
FROM (
SELECT username, auctionbids.itemid, auctionitems.description, bidamt FROM AuctionBids
INNER JOIN users ON auctionbids.userid = users.id
INNER JOIN auctionitems ON auctionbids.itemid = auctionitems.itemid
) AS am
GROUP BY am.itemid
Without example data, it is impossible to verify this works correctly. But you will need to match the bidamt with the MAX bidamt for a particular item.
SELECT DISTINCT
users.username,
auctionbids.itemid,
auctionitems.description,
auctionbids.bidamt
FROM
users
INNER JOIN auctionbids on users.userid = auctionbids.userid
INNER JOIN auctionitems on auctionbids.itemid = auctionitems.itemid
WHERE
auctionbids.bidamt = (SELECT MAX(bidamt) OVER (PARTITION BY itemid, description))
AND
itemid = < whatever you want >
Thanks for the ideas which led to this query -
SELECT am.*, auctionbids.submitted, users.username, auctionitems.description
FROM
(SELECT ab.itemid, max(ab.bidamt) as bidmax
FROM
auctionbids ab
GROUP BY ab.itemid) AS am
INNER JOIN auctionbids ON am.itemid = auctionbids.itemid and am.bidmax = auctionbids.bidamt
INNER JOIN users ON auctionbids.userid = users.id
INNER JOIN auctionitems ON auctionbids.itemid = auctionitems.itemid
So basically the max has to be found with a group by on itemid and then the inner join with rest of the tables to fetch the attributes.

SQL INNER JOIN exception

I'm new to SQL queries and I'm trying to join two tables
I need to get all data of the followers of userID = 2
here's the error i get : Syntax error: Encountered "INNER" at line 1, column 39.
and here's the SQL query I ran :
SELECT * FROM FOLLOWER
WHERE userID = "2"
INNER JOIN USERS ON FOLLOWER.Follower_userID = USERS.userID
ORDER BY USERS.follower_count ASC
The tables in my DB are :
FOLLOWER
ID
userID
Follower_userID
USERS
userID
username
password
Nickname
P.S
I'm using Apache Derby.
Thank you so much guys.
position of where clause was incorrect
structure of SELECT query is
SELECT fields
FROM tables
WHERE conditions
ORDER BY fields
so you query should be
SELECT *
FROM FOLLOWER INNER JOIN USERS ON FOLLOWER.Follower_userID = USERS.userID
WHERE userID="2"
ORDER BY USERS.follower_count ASC
Try this statement:
SELECT * FROM FOLLOWER Fl
WHERE userID="2"
INNER JOIN USERS Us ON Us.userID = Fl.Follower_userID
ORDER BY USERS.follower_count ASC
Let me know if it's works
First use join and then where.
SELECT * FROM FOLLOWER INNER JOIN USERS ON FOLLOWER.Follower_userID = USERS.userID WHERE userID=2 ORDER BY USERS.follower_count ASC
Try this
SELECT * FROM FOLLOWER
INNER JOIN USERS
ON FOLLOWER.Follower_userID = USERS.userID
WHERE FOLLOWER.userID="2"
ORDER BY USERS.follower_count ASC
Hope this helps
The Inner Join syntax
SELECT *
FROM Table1 AS T1
INNER JOIN Table2 AS T2
ON T1.Table1ColName = T2.Table2ColName
ORDER BY T1.Table1ColName
Refer this link for Inner Join
Change your query like
SELECT * FROM FOLLOWER
INNER JOIN USERS
ON FOLLOWER.Follower_userID = USERS.userID
WHERE userID="2"
ORDER BY USERS.follower_count ASC
The rules of where with join is first made all join and then give where condition which filter more data..
so your where condition just put after inner join as above all suggested.
select *
from yourtable
join yourothertable
where condition if you want
http://bytes.com/topic/sql-server/answers/850159-performance-conditions-where-clause-vs-conditions-inner-join

sql, sqlite SELECT with inner join

I'm wondering how to select one column twice using an inner joinor some other way. my database is sqlite and i use PDO db driver.
My Example:
SELECT
orders.id,
orders.order_number,
clients.first_name,
clients.last_name,
users.name AS user_name
FROM orders
INNER JOIN clients ON
orders.client_id = clients.id
INNER JOIN users ON
orders.created_by = users.id
I want to get also, the user_name who edited this record
orders.edited_by = users.id
How to join this selection?
You'll need to use table aliases.
SELECT
orders.id,
orders.order_number,
clients.first_name,
clients.last_name,
creator.name AS creator_user_name
editor.name AS editor_user_name
FROM orders
INNER JOIN clients ON
orders.client_id = clients.id
INNER JOIN users creator ON
orders.created_by = creator.id
INNER JOIN users editor ON
orders.edited_by = editor.id
Use aliases in your table names, so you can use multiple references to the same table. This also can help make large queries easier to read.
SELECT
orders.id,
orders.order_number,
clients.first_name,
clients.last_name,
createUsers.name AS creator_name,
editUsers.name AS editor_name
FROM orders
INNER JOIN clients ON
orders.client_id = clients.id
INNER JOIN users As createUsers ON
orders.created_by = users.id
INNER JOIN users As editUsers ON
orders.edited_by = users.id
You can use as many "instances" of the same table as you wish.

Why does this query return nothing?

This query works fine but I'm having trouble trying to figure out why it does not return anything if the user does not have any categories in the table "user_categories"? This is the table structure:
users: user id, username, user city
categories: category id, category name
user_categories: user id, category id
SELECT users.*, GROUP_CONCAT(categories.category_name) AS categories
FROM users
INNER JOIN user_categories ON users.user_id = user_categories.user_id
INNER JOIN categories ON user_categories.category_id = categories.category_id
WHERE users.user_city = 'brooklyn'
GROUP BY users.user_id
LIMIT 10
I just need for the new column "categories" to be empty if no rows existed for the user_id in user_categories...
Thanks!
You are using the wrong type of join - inner join will only succeed if a match is found in both tables. Instead, you want to try an outer join. Try something like this:
SELECT users.*, GROUP_CONCAT(categories.category_name) AS categories
FROM users
LEFT OUTER JOIN user_categories ON users.user_id = user_categories.user_id
LEFT OUTER JOIN categories ON user_categories.category_id = categories.category_id
WHERE users.user_city = 'brooklyn'
GROUP BY users.user_id
LIMIT 10
The Wikipedia SQL JOIN article is a pretty decent summary of the join types available.
SELECT users.*, GROUP_CONCAT(categories.category_name) AS categories
FROM users
LEFT JOIN
user_categories ON users.user_id = user_categories.user_id
LEFT JOIN
categories ON user_categories.category_id = categories.category_id
WHERE users.user_city = 'brooklyn'
GROUP BY
users.user_id
LIMIT 10
Note that on a MyISAM table, a subquery solution will probably be more efficient:
SELECT users.*,
(
SELECT GROUP_CONCAT(category_name)
FROM user_categories uc
JOIN categories c
ON c.category_id = uc.category_id
WHERE uc.user_id = users.id
) AS categories
FROM users
WHERE users.user_city = 'brooklyn'
ORDER BY
user_id
LIMIT 10
See this article in my blog for more detail:
Aggregates: subqueries vs. GROUP BY
An inner join will not return a record if there is not a record in both tables. You may be wanting a left outer join.
That's because you use an INNER JOIN to user_categories. If you use a LEFT JOIN, null data will be returned for that table if there is no corresponding ID for the user.