How to use properly INSERT INTO SELECT? - mysql

I'm trying to insert records from other tables into store_orders_items.
For example:
INSERT INTO store_orders_items( order_id, sel_item_id, sel_item_price)
SELECT order_id, sel_item_id, sel_item_price
FROM orders_ids
INNER JOIN store_orders ON store_orders.id = orders_ids.order_id
INNER JOIN store_shoppertrack ON store_items.id=store_shoppertrack.sel_item_id
Where session_id = '".$_COOKIE["PHPSESSID"]."';
Then I received the following message: Unknown column 'sel_item_price' in 'field list'. I tried to set sel_item_price As item_price to no avail.
Here are my tables:
store_orders_items:
id| order_id | sel_item_id |sel_item_price|
-------------------------------------------
| | | |
store_shoppertrack:
id| session_id | sel_item_id |date_added|
-------------------------------------------
| | | |
store_orders:
id| item_total| order_date|
---------------------------
| | |
store_items:
id| item_price| item_color|
---------------------------
| | |
orders_ids:
id| order_id | status|
----------------------
| | |

There is no table in jour join which has either a column named sel_item_price, nor a column item_price. The INSERT INTO has nothing to do with this, the SELECT on its own will fail just as well. I assume that you wanted to join with the store_items table as well, and select the item_price column from that table for insertion into the sel_item_price table of store_order_items. You could rewrite your SELECT like this:
SELECT order_id, store_shoppertrack.sel_item_id, store_items.item_price AS sel_item_price
FROM orders_ids
INNER JOIN store_orders ON store_orders.id = orders_ids.order_id
INNER JOIN store_items ON store_items.id = store_orders.sel_item_id
INNER JOIN store_shoppertrack ON store_items.id=store_shoppertrack.sel_item_id
Where session_id = 'foo';
The AS sel_item_price is optional, since you already specified the destination column in the INSERT INTO part. But it might help consistency, as the output of the SELECT will now hace volumns labeled the same as those of the target table. And it exhibits that you got the order of the AS wrong in your question, so you might learn something here.
I've created a SQL Fiddle for your schema and query.

The field sel_item_price is only in your store_orders_items table which is not part of your select query. This is the cause of the error you listed.

You need to also join against store_items, and include the column item_price from this table in your SELECT, not store_item_price which only exists in the table you are inserting into

According to this tables the only field sel_item_price is in the table store_orders_items which is the one you are going to insert the data. Thats why you got the error.

Your Query should be, you are using store_items alias but it is not in your join
INSERT INTO store_orders_items( order_id, sel_item_id, sel_item_price)
SELECT order_id, sel_item_id, sel_item_price
FROM orders_ids
INNER JOIN store_orders ON store_orders.id = orders_ids.order_id
INNER JOIN store_order_items
ON store_orders.id = store_order_items.order_id --missing
INNER JOIN store_shoppertrack
ON store_items.id=store_shoppertrack.sel_item_id
Where session_id = '".$_COOKIE["PHPSESSID"]."';

Related

SQL Nested Query to select in two tables

My database has two tables.
food_table:
+----+----------+---------------+
| ID | NAME | NutrientID |
+----+----------+---------------+
nutrient_table:
+------------+--------------+
| NutrientID | NutrientName |
+------------+--------------+
I want select all rows in food table, but get NutrientName instead of nutrientID.
If I do:
select * from food_table.
I will get NutrientID. Is it possible to get NutrientName in a single query?
SELECT f.*, n.NutrientName FROM food_table f
LEFT JOIN nutrient_table n
ON n.NutrientID = f.NutrientID
You need to make a join inner to tables filtering by field NutrientID , if you look this field as the same in two table and the join works fine.

select in mysql joining two tables with two instance of second table column

Sorry I really can't construct a good title, but let me elaborate it. :(
I have table report and table user_account.
report table have columns:
user_id | reported_user_id | date
user_account table have columns:
user_id | name | email
I need to get the name of users who reported and name of the user who was reported in one column.
It's like :
user_id | name | reported_user_id | name | email | date
I've tried left join, but I only have this:
user_id | reported_user_id | name | email
This is my statement:
select user_account.name, user_account.email, report.*
from report
left join user_account where user_account.user_id = report.reported_user_id;
Please enlighten my mind. Thank you.
select reporter.name as reporter_name, reported.name as reported_name
from report
left join user_account reporter on report.user_id = reporter.user_id
left join user_account reported on report.reported_user_id = reported.user_id

MySQL join and column names

Let's say that I have the following tables in my MySQL database:
TABLE Products
| id | some_column1 | some_column2 |
TABLE ProductProperties
| id | product_id | name |
Oversimplified, but sufficient. Now I want to get all products with properties. I do:
SELECT * FROM `Products` JOIN `ProductProperties` ON Products.id = ProductProperties.product_id
What do I get?
| id | some_column1 | some_column2 | id | product_id | name |
It's not cool, and I want to make it cool in one of the two ways:
1) To get the array of objects like in Product table, but extended by one more member, which would be the array of properties which matched JOIN. I've sort of figured out already that it's impossible?
2) To get the array like this (I'd still have to iterate over it in PHP to join all properties in one product into one object):
| product_id | some_column1 | some_column2 | property_id | product_id | name |
So I'd like to rename the column ProductProperties.id into ProductProperties.property_id. If I could remove ProductProperties.product_id from the output too, that would be ideal, but for now, I only want the way to rename one column in the output. Or to prefix it by table name. Or something like that.
Doable?
You should explicitly name the columns and not use *. Then, don't return redundant columns:
SELECT p.id as productid, p.some_column1, p.some_column2,
pp.id as ProductPropertiesId, pp.name
FROM `Products` p JOIN `ProductProperties` pp
ON p.id = pp.product_id
Also, table aliases make such a query more readable.
SELECT Products.id product_id,
Products.some_column1,
Products.some_column2,
ProductProperties.id property_id,
ProductProperties.name
FROM `Products`
JOIN `ProductProperties`
ON Products.id = ProductProperties.product_id

MySQL select distinct across multiple tables

I have a query that selects all columns from multiple tables, but it's returning multiples of the same values (I only want distinct values).
How can I incorporate something like this? When I try this, it still
Select Distinct A.*, B.*, C.*....
Does distinct only work when selecting the column names and not all (*) ? In this reference it says distinct in reference to column names, not across all of the tables. Is there any way that I can do this?
edit - I added more info below
Sorry guys, I just got back onto my computer. Also, I just realized that my query itself is the issue, and Distinct has nothing to do with it.
So, the overall goal of my Query is to do the following
Generate a list of friends that a user has
Go through the friends and check their activities (posting, adding friends, etc..)
Display a list of friends and their activities sorted by date (I guess like a facebook wall kind of deal).
Here are my tables
update_id | update | userid | timestamp //updates table
post_id | post | userid | timestamp //posts table
user_1 | user_2 | status | timestamp //friends table
Here is my query
SELECT U.* , P.* ,F.* FROM posts AS P
JOIN updates AS U ON P.userid = U.userid
JOIN friends AS F ON P.userid = F.user_2 or F.user_1
WHERE P.userid IN (
select user_1 from friends where user_2 = '1'
union
select user_2 from friends where user_1 = '1'
union
select userid from org_members where org_id = '1'
union
select org_id from org_members where userid = '1'
)
ORDER BY P.timestamp, U.timestamp, F.timestamp limit 30
The issue I'm having with this (that I thought was related to distinct), is that if values are found to meet the requirements in, say table Friends, a value for the Posts table will appear too. This means when I'm displaying the output of the SQL statement, it appears as if the Posts value is shown multiple times, when the actual values I'm looking for are also displayed
The output will appear something like this (notice difference between post value in the rows)
update_id | update | userid | timestamp | post_id | post | userid | timestamp | user_1 | user_2 | status | timestamp
1 | update1 | 1 | 02/01/2013 | 1 | post1| 1 | 2/02/2013| 1 | 2 | 1 | 01/30/2013
1 | update1 | 1 | 02/01/2013 | 2 | post2| 1 | 2/03/2013| 1 | 2 | 1 | 01/30/2013
So, as you can see, I thought I was having a distinct issue (because update1 appeared both times), but the query actually just selects all the values regardless. I get the results I'm looking for in the Post table, but all the other values are returned. So, when I display the table in PHP/HTML, the Post value will display, but I also get duplicates of the updates (just for this example)
When you select distinct *, you select every row, including the one that makes the record unique. If you want something better than what you are getting, you have to type the individual column names in your select clause.
It would be easy if you explain a little more what is the connection between the tables you'r querying, because you can use joins, unions (as mentioned above) or even group by's ...
Your updated post shows one of the JOIN conditions as:
JOIN friends AS F ON P.userid = F.user_2 OR F.user_1
This is equivalent to:
JOIN friends AS F ON (P.userid = F.user_2 OR F.user_1 != 0)
and will include many rows that you did not intend to include.
You probably intended:
JOIN friends AS F ON (P.userid = F.user_2 OR P.userid = F.user_1)
I think you want this:
select *
from tableA
union
select *
from tableB
union
select *
from tableC
This assumes that HHS tables all have the same number of columns and they are of the same data type. This not, you'll have to select specific columns to make it so.

mysql - selecting groups and users all in same query

I have following two tables 'USERS' and 'GROUPS':
USERS
-id
-name
-groupid
GROUP
-id
-name
I'd like to return all users along with their group's name and group id. It should be an outer join on group id field correct?
A simple INNER JOIN should be enough:
SELECT `USERS`.*, `GROUP`.name AS group_name
FROM `USERS`, `GROUP`
WHERE `USERS`.groupid = `GROUP`.id
You're going to want to look at the JOIN statement
Doing this from my phone, so pardon any moderately incorrect syntax, but something a long the lines of
Edit: other guy's syntax is better. It's too early here
You can use a LEFT JOIN between users and groups so that users who are not in a group still show up in the result set, but with group name and id NULL:
SELECT
a.*,
b.name AS group_name
FROM
users a
LEFT JOIN
`group` b ON a.group_id = b.id
Side note: Ensure that you're encasing the table name group in backticks because it is a reserved keyword.
The result-set should look something like:
id | name | group_id | group_name
-----------------------------------------------------------------------------
1 | John | 5 | ThisIsGroup5
3 | Tim | 3 | ThisIsGroup3
6 | NotInGroup | NULL | NULL
Changing LEFT to INNER in the above query would INNER JOIN the two tables and exclude the user "NotInGroup" from the result-set.