Not sure if the title explains the situation right but I will try to do my best explaining here.
I have a table with 3 fields linked to other tables and I want to get all the Rows grouped in the following way:
item_id, user_id, group_id
1 2 3
2 2 3
3 4 5
4 2 4
In my query i want in comma separated format all the items_id grouped by group_id i also have some extra conditions on the WHERE clause that's why the inner join
That i can do like with this query
"SELECT
GROUP_CONCAT( DISTINCT A.item_id ) AS ids
FROM tableA A
INNER JOIN tableB B ON(tableA.id = tableB.id)
WHERE xxxxx
GROUP BY A.group_id
"
Later i can loop the results and using the comma separated to inner loop every id within the result
But i also want to group it by user_id in order to do something like this
foreach( query_results.... ){
foreach( group_id.... ){
foreach( item_id.... ){
// Display info
}
}
}
Any ideas on this?
using subqueries, we can get both itemids, userids as two seperate columns
select T1.group_id, T1.itemids, T2.userids
FROM
(SELECT group_id,
GROUP_CONCAT( DISTINCT A.item_id ) AS itemids
FROM table1 A
group by group_id) T1
INNER JOIN
(
SELECT
group_id, GROUP_CONCAT( DISTINCT A.user_id ) AS userids
FROM table1 A
group by group_id
) T2
on T1.group_id = T2.group_id
Use 2 GROUP_CONCATS
SELECT GROUP_CONCAT( DISTINCT A.item_id ) AS ids,
GROUP_CONCAT( DISTINCT A.group_id ) AS groups
FROM tableA A
INNER JOIN tableB B ON(tableA.id = tableB.id)
WHERE xxxxx
GROUP BY A.group_id
Loop your resource then use Explode on the groups and ids value and loop them both as you want
Related
Sum of a multiplication of two columns grouped by another column in an inner join of three tables returns wrong value.
Below are my three tables:
Table1:
Table2:
Table3:
My Query is as below:
SELECT c.price, c.quantity, SUM( c.quantity * c.price ) AS price,
group_concat( a.rate
SEPARATOR '<br>' ) AS rates, c.hsn AS hsn
FROM tax_wa a
INNER JOIN tax_rate_class b ON a.tax_rate_id = b.tax_rate_id
INNER JOIN inv_item c ON b.tax_class_id = c.tax_class_id
WHERE c.invoice_id = '17'
GROUP BY c.hsn
And the result is:
But above one is not correct... To expain it, if you run the below query on the inv_item table (alone, with no joins) you get correct results:
SELECT price, quantity, sum( quantity * price )
FROM `inv_item`
WHERE invoice_id = '17'
GROUP BY hsn
Result is good:
Above result the wrong value calculated
if you add all
Presumably, you want the sum():
SELECT SUM(c.price), SUM(c.quantity), SUM( c.quantity * c.price ) AS price,
group_concat( a.rate SEPARATOR '<br>' ) AS rates, c.hsn AS hsn
FROM tax_wa a INNER JOIN
tax_rate_class b
ON a.tax_rate_id = b.tax_rate_id INNER JOIN
inv_item c
ON b.tax_class_id = c.tax_class_id
WHERE c.invoice_id = 17
GROUP BY c.hsn;
I know that this question asked frequently but i didn't find any answer (or that its not possible):
I'v got this query
SELECT
`items`.`id`,
`items`.`part_number`,
`item_categories`.`name` AS category,
`suppliers`.`name` AS supplier,
`items`.`supplier_id`,
`items`.`name`,
`items`.`inventory`,
`items`.`package_items`,
`items`.`order_step`,
`items`.`price`,
`items`.`discount`,
`items`.`scale`,
`items`.`by_scale`,
`items`.`has_tax`,
`items`.`category_id`,
`items`.`enable`,
orders.last_orders_amount
FROM
`items`
INNER JOIN
`suppliers` ON `items`.`supplier_id` = `suppliers`.`id`
INNER JOIN
`item_categories` ON `items`.`category_id` = `item_categories`.`id`
INNER JOIN (
SELECT
GROUP_CONCAT(
JSON_EXTRACT(
`orders`.`items`,
CONCAT('$."',
"3",
'".amount')
)
ORDER BY
`orders`.`createDate` DESC
) AS last_orders_amount
FROM
`orders`
WHERE
JSON_EXTRACT(`orders`.`items`,
'$."3"') IS NOT NULL
LIMIT 4
) orders ON orders.last_orders_amount IS NOT NULL
WHERE
1
basically i want to get all the 'items' with there last 4 occurrences in 'orders' base on item.id.
I need to replace the number 3 in that query to item.id from the outer join
(i know that there is INNER JOIN cause to get only items that have occurrences in orders)
Okay so I have three(3) tables that i want to join together
tableA is the main details and primary key is row_id autoincremented
tableB is the exteded details and primary/foreign key is row_id coming from tableA
tableC stores unordered ratings and comments for a particular row_id
I want to join all these tables so that I can see all details plus the number of instances in tableC for a row_id and the avg rating.
SELECT *
FROM `tableA` A
LEFT JOIN `tableB` B
ON A.`row_id` = B.`row_id`
LEFT JOIN (
SELECT COUNT( 1 ) AS 'count', Avg(`row_rating`) AS 'avg'
FROM `tableC`
GROUP BY tableC.`row_id`
)C
ON C.`row_id` = A.`row_id`
ORDER BY C.`avg` ASC
The result of this query combines all properly but the same count and avg is displayed in all rows.
Looks like you want to group the records by row_id in inner query. In which case, you need to SELECT row_id instead of COUNT(1), try this:
SELECT *
FROM `tableA` A
LEFT JOIN `tableB` B
ON A.`row_id` = B.`row_id`
LEFT JOIN (
SELECT row_id, Avg(`row_rating`) AS 'avg'
FROM `tableC`
GROUP BY tableC.`row_id`
)C
ON C.`row_id` = A.`row_id`
ORDER BY C.`avg` ASC
i have a table that contains some articles with it's own ID and shared SKU key.
I've tried to make the query with a left join and using group result to take all ids returned from the query.
My data structure is like that:
id - name - sku - ...
1 - felix - cat
2 - tom - cat - ...
3 - sylvester - cat - ...
4 - red - pen - ...
5 - blue - pen - ...
I tried to use this query:
SELECT * FROM `test`
[LEFT/RIGHT/INNER] JOIN
(
SELECT GROUP_CONCAT(DISTINCT id) AS idsgroup FROM `test` WHERE (attribute_name = 'sku') GROUP BY value_name LIMIT 0, 3
) bind
ON id IN (bind.idsgroup);
this query is wrong, it return only 1 id per group instead all ids selected from concat or in LEFT JOIN case, obviously all rows.
Any suggestion workaround to achieve the right result?
EDIT:
here a fiddle with the structure:
http://sqlfiddle.com/#!9/b6747a
And the query i tried into:
SELECT * FROM `view_test`
INNER JOIN
(
SELECT GROUP_CONCAT(DISTINCT entity_id) AS idsgroup FROM `view_test` WHERE (attribute_name = 'sku') GROUP BY value_name LIMIT 0, 3
) bind
ON entity_id IN (bind.idsgroup);
As this pic show, my result lost some ids, part of the group.
EDIT 2:
after i used FIND_IN_SET() suggested by Kickstart the result is the expected:
SELECT * FROM `view_test`
INNER JOIN
(
SELECT GROUP_CONCAT(DISTINCT entity_id) AS idsgroup FROM `view_test` WHERE (attribute_name = 'sku') GROUP BY value_name LIMIT 0, 3
) bind
ON FIND_IN_SET(entity_id, bind.idsgroup);
The simple fix would appear to be to use FIND_IN_SET for the join. But this is a bit of a hack and will not be that quick.
SELECT *
FROM `view_test`
INNER JOIN
(
SELECT GROUP_CONCAT(DISTINCT entity_id) AS idsgroup
FROM `view_test`
WHERE (attribute_name = 'sku')
GROUP BY value_name
LIMIT 0, 3
) bind
ON FIND_IN_SET(entity_id, bind.idsgroup);
Further not sure why you have a LIMIT on the sub query, especially without an order clause.
Possibly better to use a sub query to just get the DISTINCT entity_id with an attribute_name of sku and join against that.
SELECT *
FROM `view_test`
INNER JOIN
(
SELECT DISTINCT entity_id
FROM `view_test`
WHERE (attribute_name = 'sku')
) bind
ON view_test.entity_id = bind.entity_id
Something like this?
SELECT t.*, group_concat(t2.id) FROM `test` t
LEFT JOIN test t2 ON t2.attribute_name = 'sku' and t.id != t2.id
group by t.id;
row, and the list of all ids that have same SKU
I currently have this left join as part of a query:
LEFT JOIN movies t3 ON t1.movie_id = t3.movie_id AND t3.popularity = 0
The trouble is that if there are several movies with the same name and same popularity (don't ask, it just is that way :-) ) then duplicate results are returned.
All that to say, I would like to limit the result of the left join to one.
I tried this:
LEFT JOIN
(SELECT t3.movie_name FROM movies t3 WHERE t3.popularity = 0 LIMIT 1)
ON t1.movie_id = t3.movie_id AND t3.popularity = 0
The second query dies with the error:
Every derived table must have its own alias
I know what I'm asking is slightly vague since I'm not providing the full query, but is what I'm asking generally possible?
The error is clear -- you just need to create an alias for the subquery following its closing ) and use it in your ON clause since every table, derived or real, must have its own identifier. Then, you'll need to include movie_id in the subquery's select list to be able to join on it. Since the subquery already includes WHERE popularity = 0, you don't need to include it in the join's ON clause.
LEFT JOIN (
SELECT
movie_id,
movie_name
FROM movies
WHERE popularity = 0
ORDER BY movie_name
LIMIT 1
) the_alias ON t1.movie_id = the_alias.movie_id
If you are using one of these columns in the outer SELECT, reference it via the_alias.movie_name for example.
Update after understanding the requirement better:
To get one per group to join against, you can use an aggregate MAX() or MIN() on the movie_id and group it in the subquery. No subquery LIMIT is then necessary -- you'll receive the first movie_id per name withMIN() or the last with MAX().
LEFT JOIN (
SELECT
movie_name,
MIN(movie_id) AS movie_id
FROM movies
WHERE popularity = 0
GROUP BY movie_name
) the_alias ON t1.movie_id = the_alias.movie_id
LEFT JOIN movies as m ON m.id = (
SELECT id FROM movies mm WHERE mm.movie_id = t1.movie_id
ORDER BY mm.id DESC
LIMIT 1
)
you could try to add GROUP BY t3.movie_id to the first query
Try this:
LEFT JOIN
(
SELECT t3.movie_name, t3.popularity
FROM movies t3 WHERE t3.popularity = 0 LIMIT 1
) XX
ON t1.movie_id = XX.movie_id AND XX.popularity = 0
On MySQL 5.7+ use ANY_VALUE & GROUP_BY:
SELECT t1.id,t1.movie_name, ANY_VALUE(t3.popularity) popularity
FROM t1
LEFT JOIN t3 ON (t3.movie_id=t1.movie_id AND t3.popularity=0)
GROUP BY t1.id
more info
LEFT JOIN only first row
https://dev.mysql.com/doc/refman/5.7/en/group-by-handling.html
Easy solution to left join the 1 most/least recent row is using select over ON phrase
SELECT A.ID, A.Name, B.Content
FROM A
LEFT JOIN B
ON A.id = (SELECT MAX(id) FROM B WHERE id = A.id)
Where A.id is the auto-incremental primary key.
LEFT JOIN (
SELECT id,movie_name FROM movies GROUP BY id
) as m ON (
m.id = x.id
)
// Mysql
SELECT SUM(db.item_sales_nsv) as total FROM app_product_hqsales_otc as db
LEFT JOIN app_item_target_otc as it ON
db.id = (SELECT MAX(id) FROM app_item_target_otc as ot WHERE id = db.id)
and db.head_quarter = it.hqcode
AND db.aaina_item_code = it.aaina_item_code AND db.month = it.month
AND db.year = it.year
WHERE db.head_quarter = 'WIN001' AND db.month = '5' AND db.year = '2022' AND db.status = '1'