I couldn't think of a better way to ask this question, but here goes:
I have 2 tables. The first is a table of items for label printing jobs. We'll call it pj_items The columns are simply: job_id, part_num and qty
The second table is a list of finishes called PartFinishes on parts with just 2 columns of: PartNumber and FinishId
When I want to retrieve information for the label printer I use:
select pj_items.part_num, pj_items.qty, PartFinishes.FinishId from pj_items
join PartFinishes on PartFinishes.PartNumber = pj_items.part_num
where job_id = 1
This query works fine and gives me the right result when each part has only one finish. The problem is when there are 2 or more finishes on a part.
For example: The part 99401326 has 2 finishes. On my pj_items table I have one row for that part so I can print one label. When I use this query it returns 2 rows for that part each with a different FinishId Unfortunately that would result in 2 labels printed. I need both of those finishes on one row since I only want one label printed with both FinishId's present.
I had a similar query which returned the finishes as new columns (f1,f2,f3) But it would still return 2 rows in the given example with f1 defined in the first row and f1 as null in the second row and f2 being defined in the second.
How can I get that into one row?
Hopefully that makes sense, anyone have any suggestions?
If you need anymore info, let me know.
Thanks!
EDIT:
The pj_items table may have duplicate entries and I need to preserve those as separate rows. I just need to have all the finishes for each part in one row with its respective part.
Example
Here is an example of the pj_items table:
Here is the relevant information from the PartFinishes table:
And here is the result using the original query:
What I need in the result is the two rows of 99401326 are one with both of the finishes in that row, while maintaining the 2 seperate rows for the 99401077 since I want 2 labels of those.
You can use GROUP_CONCAT to combine all finish ID's for a given part into one column.
SELECT pj_items.part_num,
pj_items.qty,
GROUP_CONCAT(PartFinishes.FinishId) as FinishIds
FROM pj_items
JOIN PartFinishes
ON PartFinishes.PartNumber = pj_items.part_num
WHERE job_id = 1
GROUP BY PartFinishes.PartNumber
#comment:
However if you want to keep rows from pj_items separated you will need to join PartFinishes already grouped by PartNumber:
SELECT pj_items.part_num,
pj_items.qty,
FinishesGrouped.FinishIds
FROM pj_items
JOIN
( SELECT PartNumber, GROUP_CONCAT(FinishId) as FinishIds
FROM PartFinishes
GROUP BY PartNumber ) FinishesGrouped
ON
pj_items.part_num = FinishesGrouped.PartNumber
Related
I have a query i have been working on trying to get a specific set of data, join the comments in duplicate phone numbers of said data, then join separate tables based on a common field "entry_id" which also happens to be the number on the end of the word custom_ to pull up that table.
table named list and tables containing the values i want to join is custom_entry_id (with entry_id being a field in list in which i need the values of each record to replace the words in order to pull up that specific table) i need entry_id from the beginning part of my query to stick onto the end of the word custom for every value my search returns to get the fields from that custom table designated for that record. so it will have to do some sort of loop i guess? sorry like i said I am at a loss at this point
this is where i am so far:
SELECT * ,
group_concat(comments SEPARATOR '\r\n\r\n') AS comments_combined
FROM list WHERE `status` IN ("SALEA","SALE")
GROUP BY phone_number
//entry_id is included in the * as well as status
// group concat combines the comments if numbers are same
i have also experimented on test data with doing a full outer join which doesnt really exist. i feel if you can solve the other part for me i can do the joining of the data with a query similar to this.
SELECT * FROM test
LEFT JOIN custom_sally ON test.num = custom_sally.num
UNION
SELECT * FROM test
RIGHT JOIN custom_sally ON test.num = custom_sally.num
i would like all of this to appear with every field from my list table in addition to all the fields in the custom_'entry_id' tables for each specific record. I am ok with values being null for records that have different custom fields. so if record 1 has custom fields after the join of hats and trousers and record 2 has socks and shoes i realize that socks and shoes for record 1 will be null and hats and trousers for record 2 will be null.
i am doing all this in phpmyadmin under the SQL tab.
if that is a mistake please advise as well. i am using it because ive only been working with SQl for a few months. from what i read its the rookie tool.
i might be going about this all wrong if so please advise
an example
i query list with my query i get 20,000 rows with columns like status, phone_number, comments, entry_id, name, address, so on.
now i want to join this query with custom fields in another table.
the problem is the custom tables' names are all linked to the entry_id.
so if entry_id is 777 then the custom table fields are custom_777
my database has over 100 custom tables with specials fields for each record depending on its entry_id.
when i query the records I don't know how to join the custom fields that are entry_id specific to the rest of my data.i will pull up some tables and data for a better example
this is the list table:
this is the custom_"entry_id"
Full Outer Join in MySQL
for info on full outer joins.
I have a database of users and user items of which each user can have multiple items linked to their account.
The problem im having with my current SELECT query is I want to return each user once but with all the rows tied to that user sort of like this:
User 1 ¬
item id 1
item id 2
item id 3
User 2 ¬
item id 1
item id 3
etc
This would be my ideal fetch results so i can process the data correctly by simple looping... so i tried a left join but this did not work.
I am wondering how do I fetch the results like the above? This is my current query:
SELECT U.user_id, I.item_name
FROM users U
LEFT JOIN user_items UI ON U.user_id = UI.user_id
INNER JOIN items I ON I.item_id = UI.item_id
Currently if a user has two or more items, I get duplicated data for User ID which I'm trying to avoid.
If I understand the problem correctly, you are trying to traverse a master/detail relationship.
Whenever you use JOINs, the engine will output every matching set of rows. In this case, if a user has more than 1 item, it will appear along with every one of them. That is not something you can avoid, as you cannot have a result set with a varying amount of columns or something like "do not output this column if the previous one has the same value". I wouldn't try to solve it adjusting the query. The LEFT JOIN will only help you if you want to have also every user that doesn't have any items.
In order to get the output you want, you need to work with the result set. For instance, you could order the results by user_id, then traverse the set and printing the user_id only when it changes. Another option would be to use 2 queries: one to get every user (you can narrow it to every one that has at least one item, if you want), and another to get the items for each user, traversing the results from the first query.
Both solutions require you to process the results, by means of a stored procedure, or a programming language.
Hope this helps!
I've read numerous tutorials and graphical representations of MySQL joins, and they still don't make sense to me.
I'm trying to type my own now, and they are working, but I just don't see how they're working.
Take this set of tables
images squares
---------------------------- ----------------------------------
image_id | name | square_id square_id | latitude | longitude
---------------------------- ----------------------------------
1 someImg 14 1 42.333 24.232
2 newImg 3 2 38.322 49.2320
3 blandImg 76 3 11.2345 99.4323
... ...
n n
This is a one to many relationship - one square can have many images, but an image can only have one square.
Now I run this simple join, but I'm not understanding the syntax of it at all...
SELECT images.image_id
FROM squares
LEFT JOIN images ON images.square_id=squares.square_id
WHERE images.square_id=711464;
Now, this actually works, which amazes me. It brings up a list of images within the square range.
But I'm having a hard time understanding the ON syntax.
What does ON do exactly?
Does it show how the two tables are related?
Mainly however, SELECT images.image_id FROM squares, makes the least sense.
How can I select a field in one table but FROM another?
Let's start with the FROM clause, which in it's entirety is:
FROM squares LEFT JOIN images ON images.square_id=squares.square_id
(it's not just FROM squares).
This defines the source of your data. You specify both tables, squares and images so they are both sources for the data that the query will work on.
Next, you use the on syntax to explain how this tables are related to one another. images.square_id=squares.square_id means: consider a row in the images table related to a row in the squares table if and only if the value of the field square_id of the images row is equal to the value of the field square_id of the squares table. At this moment, each row of the result is a combination of a row from the images table and a row from the squares table (I'll ignore the LEFT JOIN at the moment).
Next, you have the WHERE clause
WHERE images.square_id=711464
This means, from the rows that are in result set, just get those where the value of the square_id field, in that part of the result row that came from the images table, is exactly 711464.
And last comes the SELECT part.
SELECT images.image_id
This means, from the rows that are in the result set (a combination of a square row and a images row), take just the field image_id that is from the images table.
You should read the query as such:
SELECT images.image_id FROM
squares LEFT JOIN images
ON images.square_id=squares.square_id
WHERE
images.square_id=711464
So you first join the squares table with the images table, combining entries in images which have the same square_id as in the squares table. So, the ON syntax is actually specifying the condition on which the two tables should be joined.
Then, you do a filter using WHERE, which will take the entries with square_id=711464
Note that by the time you do the SELECT, you already joined the two tables, which will have the combined fields:
images
--------------------------------------------------
square_id | latitude | longitude | image_id | name
--------------------------------------------------
So, you can select the square_id from the resulting table.
It is more like :
SELECT images.image_id FROM (squares LEFT JOIN images ON images.square_id=squares.square_id WHERE images.square_id=711464)
So you don't select a field from another table - it is more like you create a new temporary table from the statement in brackets (actually having columns from multiple tables) and then perform SELECT on this table.
And yes, ON defines how the tables are related (for instance with foreign key)
SELECT [COLUMNS] --First Line Of Code - say it as 1
FROM --Second Line Of Code -- say it as 2
[Table1] Join [table2] On [Criteria] --say it as 3
Where [Some More Criteria] --Say it as 4
Whenever a
Select Column From
is done it gets the data from 3 which is collection of multiple table or single table.
Once the data is loaded it Executes the where criteria for filtering the data.
After data filtration Select statement will be Executed.
In your case:
Left Join will execute and generate table with 6 columns. based on Join Criteria. Than Where criteria will be executed to filter the data.
Select statement execution will takes place only after that.
Regarding using the Table Name as prefix is to avoid the conflict in Column Name.
P.S : This is for your understanding, actually the data load doesn't happen. To understand exactly how queries are executed you need to understand DB Engine.
As Of Now,Write query and leave the DB Engine for planning.
With Experience Comes The Knowledge.
Happy Coding
I am trying to run an update query based on 2 fields in a seperate table. I know how to do it based on one field, add the two tables, create a join between the two related fields and run the update. However when I try and run it with two joins it says it cannot execute because it contains ambiquous joins. Here's a brief example of what I'm trying to achieve
Table 1 contains name, location and number of items.
Table 2 contains name, location and and empty field for the number of items.
When i try update table 2 with the information from table 1, with a join between the 2 name fields, it updates the same number of items for each different location.
UPDATE:
I've fixed it, I think I was linking the joins incorrectly.
Here's the finished SQL statement:
UPDATE Tbl_Hourly_Pick_Performance
LEFT JOIN Tbl_Temp_Count_Info
ON (Tbl_Hourly_Pick_Performance.[Sign On]=Tbl_Temp_Count_Info.[Picker ID])
AND (Tbl_Hourly_Pick_Performance.[Pick Floor]=Tbl_Temp_Count_Info.Floor)
SET Tbl_Hourly_Pick_Performance.[No of Stores] = Tbl_Temp_Count_Info.Count;
I have a 1 to many relationship between people and notes about them. There can be 0 or more notes per person.
I need to bring all the notes together into a single field and since there are not going to be many people with notes and I plan to only bring in the first 3 notes per person I thought I could do this using at most 3 queries to gather all my information.
My problem is in geting the mySQL query together to get the first, second, etc note per person.
I have a query that lets me know how many notes each person has and I have that in my table. I tried something like
SELECT
f_note, f_person_id
FROM
t_person_table,
t_note_table
WHERE
t_person_table.f_number_of_notes > 0
AND t_person_table.f_person_id = t_note_table.f_person_id
GROUP BY
t_person_table.f_person_id
LIMIT 1 OFFSET 0
I had hoped to run this up to 3 times changing the OFFSET to 1 and then 2 but all I get is just one note coming back, not one note per person.
I hope this is clear, if not read on for an example:
I have 3 people in the table. One person (A) has 0 notes, one (B) with 1 and one (C) with 2.
First I would get the first note for person B and C and insert those into my person table note field.
Then I would get the second note for person C and add that to the note field in the person table.
In the end I would have notes for persons B and C where the note field for person C would be a concatination of their 2 notes.
Welcome to SO. The thing you're trying to do, selecting the three most recent items from a table for each person mentioned, is not easy in MySQL. But it is possible. See this question.
Select number of rows for each group where two column values makes one group
and, see my answer to it.
Select number of rows for each group where two column values makes one group
Once you have a query giving you the three rows, you can use GROUP_CONCAT() ... GROUP BY to aggregate the note fields.
You can get one note per person using a nested query like this:
SELECT
f_person_id,
(SELECT f_note
FROM t_note_table
WHERE t_person_table.f_person_id = t_note_table.f_person_id
LIMIT 1) AS note
FROM
t_person_table
WHERE
t_person_table.f_number_of_notes > 0
Note that tables in SQL are basically without a defined inherent order, so you should use some form or ORDER BY in the subquery. Otherwise, your results might be random, and repeated runs asking for different notes might unexpectedly return the same data.
If you only aim for a concatenation of notes in any case, then you can use the GROUP_CONCAT function to combine all notes into a single column.