Select Query for these tables - php

I have two tables items and item_details.
To show the items in the feeds page I use the below JOIN QUERY.
SELECT i.item_id,i.time,id.text,id.photo FROM items i LEFT JOIN item_details id ON i.item_id=id.item_id
but, it returns multiple rows of same item id. The only work around I find is first select the items table only, then select the item_detail table while looping in PHP. I feel that's not a best practice and may effect the performance.
Kindly suggest a better method to select the items.

Problem:
You are joining with item_details which has 3 records with same item_id. So the result will have more records for that item_id.
Solution:
I think this is what you after:
SELECT i.item_id,i.time,MAX(id.text) as text,MAX(id.photo) as photo
FROM items i LEFT JOIN
item_details id ON i.item_id=id.item_id
GROUP BY i.item_id,i.time
Sample result:
item_id time text photo
---------------------------------------------------------------------
2 87213 (null) (null)
4 2029 another text row for item id 4 a photo for item id 4
Sample result in SQL Fiddle
NB: This method will not work as expected if you have multiple records with same item_id having different values for text and photo columns.

Related

How to Order MYSQL Results By Number of rows in a another table

I have 2 Tables:
1 - cat
Id|category
2 - groups
Id|groupname|category
I want to sort the data from the cat table by the number of rows in the category (group) table.
For example in groups table, category row have the following data:
Education - 20
Fun - 50
Nature - 30
I wanna show cat as:
Fun
Nature
Education
How can I do it?
Can't you just count the amount of rows in the one table and order your results by the resulting count?
SELECT
*,
(SELECT COUNT(*) FROM category WHERE category.cat_id=cat.id) as count
FROM cat
ORDER BY count DESC;
Note To get a better answer, you'll need to be more specific about your table structure and what you would like to achieve.

LIMT query to 1 if selcted two tables

How to limit query to 100 if i have selected data from two tables.
But i want the limit 100 to only work on one of them.
SELECT c.* , p.*
FROM test c,test2 p
WHERE c.id=p.id_puf
LIMIT 100
But here is the tricky part(at least for me)
In table "test" ja hold names.
Structure:
ID, Name, Age
Table "test2" ja hold record of the persons and they are connected with user ID
Structure:
ID, connect(this is same as "test" id), numbers
Now every tabel row in "test" is unique
I want to get all the results for test but all the record from the "test2".
Here is how you would do it -- select the items from the first table you want and then join to the 2nd table.
SELECT *
FROM (
SELECT *
FROM test
LIMIT 100
) c
LEFT JOIN test2 p ON c.id=p.id_puf
Notice I'm using "modern" joins. The join style you were using is about 20 years out of date and is not as good. It is much clearer how to solve this problem if you are using modern joins (for example).

sum row content with matching columns

Yes yes, I know. The title is stupid and hard to understand.
Question:
There's a DB1 and a DB2.
DB1 has columns called id and price. id is a unique number for each item like 301 and so on. There's only one of each id in this DB.
DB2 contains a column named id and one named price. This DB has the duty of collecting data about each id ( item ) via a php script.
This means multiple rows with the same unique id.
a picture to demonstrate:
What i'm trying to do:
a script that querys an id ( matches the id with another table ) and sums up all the price columns with the same id.
I understand innerjoin
SELECT db1.id, db2.price
FROM db1
INNER JOIN db2
ON db1.id=db2.id;
but I want to sum all db2.price rows before showing. What can I do?
What you want is this:
(I guess you want to show db1.price too (or other fields from db1, otherwise there is no meaning have this join)
SELECT db1.id, db1.price, db2s.price -- rest of db1 fields here
FROM db1
INNER JOIN (select id, sum(price) price from db2 group by id) as db2s
ON db1.id=db2s.id;
SQLFIDDLE
I don't think you need a join for that. It should be enough to just do:
SELECT id, sum(price) as price_sum FROM db2 GROUP BY id
This should give you 2 columns:
id of the price
sum of all prices for given price ID

mysql select and join on multiple tables

I'm having tables like
product table: product_id | code
group table: id | fk-product_id | id_code
grade table id | fk-product_id | id_grade
person table id | fk-product_id | id_person
my sql query is:
"SELECT *
FROM product
JOIN group ON group.product_id = product_id
JOIN grade ON grade.product_id = product_id
JOIN person ON person.product_id = product_id
WHERE product.code='".$productCode."'");
I get the wright result, but there is too much of rows. I thing that I'm doing overkill.
All product are for sure in the table "product" but it's not necessary that the same "id_product" is in the table "group", "grade" or "person".
In my result are a lot of rows where my result is repeted. I there any way to avoid those duplication?
Is there better way to perform my query?
From your original query, you have listed the column in the group, grade and person table are
'fk-product_id' but your query is showing as just 'product_id'. So, I am implying your real column is just 'product_id' and the 'fk-' was just a reference that it was the foreign key to products table.
Now, that said, the equality comparison is just product_id. Since you are not qualifying it with alias.field, it is probably grabbing everything since each record in group will always have its own product_id = its own product_id.
In addition, you mention that not all tables will have a matching product ID, so you will need LEFT-JOINs for the other tables... Adjust to something like this
SELECT
p.*,
gp.id_code,
gd.id_grade,
per.id_person
FROM
product p
LEFT JOIN group gp
ON p.product_id = gp.product_id
LEFT JOIN grade gd
ON p.product_id = gd.product_id
LEFT JOIN person per
ON p.product_id = per.product_id
WHERE
p.code='".$productCode."'";
But I would head caution for sql-injection as you could get malicious values in your $productCode variable. Make sure you have it properly cleaned and escaped.
#5er, Left-Join says for each record on the left-side (first in this case is the Product Table), I want all records... and oh... by the way... I have the other tables (group, grade and persons). They MAY have a record too that has the same Product_ID value as the product table. If so, grab those pieces too, but don't exclude the original product record.
Now, why your query was failing, and I thought I described it well, but apparently not. You were getting a Cartesian result which means for every one record in the left-table (product), you were getting EVERY record in the RIGHT-side table... So, for a single product, and if you had 20 group, 10 grades and 100 people, you were basically getting 20,000 records.
So your JOIN
JOIN group ON group.product_id = product_id
WOULD have worked, but had less records IF you qualified with the PRODUCT reference
JOIN group ON group.product_id = PRODUCT.product_id
Otherwise, it was just comparing its own product_ID to itself and saying... Yup, these to product IDs match (even though it was the same record), it returned it. The engine can't guess for you which table you meant for the second part of the join, especially when there were a total of 4 tables referenced in the query, and EACH had a "Product_ID" column. So, I strongly suggest that for ALL your queries, qualify ALL fields as alias.field, including those of the select field list. Then, anyone else trying to help you in the future, or even take over where you left-off know where the fields are. Prevent ambiguity in your queries.
Your select does not match the table/column names above it. For example in table product you say you have column id_product, but in select you use product.id instead of product.id_product. That might be totally different column.
Your results are repeating because the JOIN is joining tables, but you are not filtering those cases where one JOIN matches, while the other isn't.
Try this:
SELECT *
FROM product
JOIN group ON group.product_id = product.id
JOIN grade ON grade.product_id = product.id
JOIN person ON person.product_id = product.id
WHERE product.code='".$productCode."'
GROUP BY product.id

mysql multi table foreign keys? - beginner

I have 2 tables,
Table1:
id, int1, int2, int3
john,1,2,4
tim,2,3,4
pete,1,3,4
Table2:
integer,blob
1,wins
2,backtickle
3,text
4,whatever
The query I want to use is given the id I want to get the blob data from table2 associated with each of the integer columns in table1.
What is the specific query I can use here?
Sample result I am looking for would be something like:
search John returns "wins","backtickle","whatever"
search pete returns "wins","text","whatever"
I think it has something to do with foreign keys, but not sure...beginner level please! With 1 table it would be SELECT * FROM table1 WHERE id="........" but not sure with the setup i have now given above.
The structure of your database does not look optimal. You're limiting yourself to 3 items per person, and you're using columns instead of rows in order to list them. What you actually have in your data is a many-to-many relationship between Table1 and Table2. What I'd recommend is using three tables:
Persons:
name, personid
john,1
tim,2
pete,3
PersonBlobs:
personid, blobid
1,1
1,2
1,4
2,2
2,3
2,4
3,1
3,3
3,4
Blobs:
blobid,blob
1,wins
2,backtickle
3,text
4,whatever
PersonBlobs would give you the many-to-many link between Persons and Blobs.
And then the query becomes:
select Blobs.blob
from Blobs inner join PersonBlobs on Blobs.blobid = PersonBlobs.blobid
inner join Persons on PersonBlobs.personid = Persons.personid
where Persons.name = 'John'

Categories