Suppose I have a table like this:
Order_ID | Box_ID | Item_ID
------------------------------------
B | 1 | b
B | 2 | b
A | 2 | a
A | 3 | a
A | 4 | a
Now when I order the table by order ID,
SELECT * FROM table ORDER BY Order_ID, Box_ID;
the result will look like this:
Order_ID | Box_ID | Item_ID
------------------------------------
A | 2 | a
A | 3 | a
A | 4 | a
B | 1 | b
B | 2 | b
But now, I want the sql statement to first consider putting same value of Box_ID together,
such that the result will look like this:
Order_ID | Box_ID | Item_ID
------------------------------------
A | 2 | a
B | 2 | b
// despite order_ID being B, but box_ID is equal to previous value, so group together
A | 3 | a
A | 4 | a
B | 1 | b
But the following code,
SELECT * FROM table ORDER BY Box_ID, Order_ID
Will produce the following result since it lists Box_ID in alphabetical order first.
Order_ID | Box_ID | Item_ID
------------------------------------
B | 1 | b
A | 2 | a
B | 2 | b
A | 3 | a
A | 4 | a
How can I output my desired result?
I think you want:
order by min(order_id) over(partition by box_id), box_id
In earlier versions, you can use a subquery:
select *
from mytable t
order by
(select min(order_id) from mytable t1 where t1.box_id = t.box_id),
box_id
In order versions of MySQL, you can use a correlated subquery:
select t.*
from table t
order by (select min(t2.order_id) from table t2 where t2.box_id = t.box_id),
box_id;
If you want the rows with most occurrences of Box_ID at the top, then you need this query:
SELECT Box_ID, COUNT(*) counter
FROM tablename
GROUP BY Box_ID
joined to the table like this:
SELECT t.*
FROM tablename t
INNER JOIN (
SELECT Box_ID, COUNT(*) counter
FROM tablename
GROUP BY Box_ID
) g ON g.Box_ID = t.Box_ID
ORDER BY g.counter DESC, Order_ID, Box_ID
See the demo.
Results:
> Order_ID | Box_ID | Item_ID
> :------- | -----: | :------
> A | 2 | a
> B | 2 | b
> A | 3 | a
> A | 4 | a
> B | 1 | b
Related
I have one table named colors and I need to create a query that returns how many unique colors are used each year based on the date in my other table, programs.
It looks like this:
colors
+----+----------+
| id | name |
+----+----------+
| 1 | blue |
| 2 | yellow |
+----+----------+
programs
+----+------------+
| id | date |
+----+------------+
| 1 | 2016-01-08 |
| 2 | 2016-02-08 |
| 3 | 2017-02-08 |
+----+------------+
programs_colors
+------------+----------+
| program_id | color_id |
+------------+----------+
| 1 | 1 |
| 1 | 1 |
| 2 | 2 |
| 2 | 1 |
| 3 | 1 |
| 3 | 1 |
+------------+----------+
I have tried with this:
SELECT min(date), count(*) FROM (
SELECT min(date) AS date FROM programs_colors INNER JOIN programs ON programs.id = program_id GROUP BY color_id
) AS a GROUP BY year(date)
min(date): count(*):
2016-01-08 2
2017-01-08 0
But the above query groups my colors as a whole, but I need them grouped by each year
Expected result:
min(date): count(*):
2016-01-08 2
2017-01-08 1
I hope my question makes sense
SELECT min(date), count(distinct color_id)
FROM programs_colors
INNER JOIN programs
ON programs.id = program_id
GROUP BY year(date);
If I understand right, you might need to do something like this
SELECT min(date), sum(count) FROM (
SELECT min(date) AS date, count(*) as count FROM programs_colors INNER JOIN programs ON programs.id = program_id GROUP BY color_id
) AS a GROUP BY year(date)
I have next table:
| ID |ID2 | price|
+----+---+----+
| A | AA | 7 |
| B | AA | 3 |
| C | AA | 4 |
| D | BB | 7 |
| I | BB | 2 |
| F | BB | 3 |
| G | CC | 9 |
| E | CC | 4 |
| K | CC | 1 |
+----+---+---+
And I need to get the next table
group by ID2 with min field price and corresponding min price field ID1
| ID1 | ID2 | min_price |
+----+---+---+----------
| B | AA | 3 |
| I | BB | 2 |
| K | CC | 1 |
+----+---+---+---------
select a.id, a.id2, a.price from #yourtable a
join
(
select id2, min(price) AS price
from #yourtable
group by id2
)b
on a.id2=b.id2 and a.price=b.price
SELECT *
FROM
#table t
INNER JOIN (
SELECT
ID2
,MIN(price) as min_price
FROM
#table
GROUP BY
ID2
) g
ON t.ID2 = g.ID2
AND t.price = g.min_price
Step 1 find the minimum price, step 2 relate back to get the original record that matches to get the ID. There are other ways to do this as well.
Note that if your dataset contains 2 records in the same ID2 with the same price then more than 1 record will always be returned.
Based on your explanation, we need to group by id2 and get the lowest price and its corresponding id.
Here is the query for the same
SELECT id,
id2,
price
FROM NEXT
WHERE (price,id2) IN
(SELECT MIN(price), id2 FROM NEXT GROUP BY id2
);
http://sqlfiddle.com/#!9/295702/2
SELECT t1.*
FROM t1
LEFT JOIN t1 t2
ON t1.id2=t2.id2
AND t1.price>t2.price
WHERE t2.ID IS NULL
After looking at other examples I still have not been able to find a solution, that is why I am asking for some help.
My table structure:
V_id | name | group_id | other columns
----------------------
1 | | 1
2 | | 1
3 | | 2
4 | | 3
5 | | 3
I have been struggling to build a query, to select all the rows which have the maximum value from the group_id column.
therefore output should be like this:
V_id | name | group_id | other columns
----------------------
4 | | 3
5 | | 3
which I believe can be solved by selecting all records where group_id is the highest.
and also need a query to get all the other remaining rows.
which in this case, should be like this:
V_id | name | group_id | other columns
----------------------
1 | | 1
2 | | 1
3 | | 2
which I believe can be done by selecting all records where group_id < Max(group_id)
for the first part of the problem,
SELECT *
FROM tableName
WHERE group_id = (SELECT MAX(group_ID) FROM TableName)
and for the second part,
SELECT *
FROM tableName
WHERE group_id < (SELECT MAX(group_ID) FROM TableName)
You can use JOIN for that:
SELECT a.*
FROM Table1 a
JOIN (SELECT MAX(Group_ID) AS MAXID
FROM Table1) B
ON a.Group_id = B.MaxID;
Result:
| V_ID | NAME | GROUP_ID |
----------------------------
| 4 | (null) | 3 |
| 5 | (null) | 3 |
For the remaining rows use LEFT JOIN with a condition like this:
SELECT a.*
FROM Table1 a
LEFT JOIN (SELECT MAX(Group_ID) AS MAXID
FROM Table1) B
ON a.Group_id = B.MaxID
WHERE B.MaxID IS NULL;
Result:
| V_ID | NAME | GROUP_ID |
----------------------------
| 1 | (null) | 1 |
| 2 | (null) | 1 |
| 3 | (null) | 2 |
See this SQLFiddle
Let's say i have query like this:
SELECT name, GROUP_CONCAT(number)
FROM objects
GROUP BY name
And it outputs:
+----------+----------------------+
| NAME | GROUP_CONCAT(NUMBER) |
+----------+----------------------+
| false_1 | 2,1 |
| false_2 | 3,4 |
| true_1 | 4,3,2,1 |
| true_2 | 2,3 |
+----------+----------------------+
Now how can i return rows having 2 AND 3 as number?
Note: This query is grouped - table has 10 rows, like so:
+---------+--------+
| NAME | NUMBER |
+---------+--------+
| true_1 | 1 |
| true_1 | 2 |
| true_1 | 3 |
| ... | ... |
+---------+--------+
[Link to SQLFiddle]
SELECT name, GROUP_CONCAT(number)
FROM objects
WHERE number IN (2,3)
GROUP BY name
HAVING COUNT(*) = 2
SEE SQLFiddle Demo
or if you want to retain all value on which the name has,
SELECT a.name, GROUP_CONCAT(A.number)
FROM objects a
INNER JOIN
(
SELECT name
FROM objects
WHERE number IN (2,3)
GROUP BY name
HAVING COUNT(*) = 2
) b ON a.Name = b.Name
GROUP BY a.name
SEE SQLFiddle Demo
How to select 1st, 2nd or 3rd value before MAX ?
usually we do it with order by and limit
SELECT * FROM table1
ORDER BY field1 DESC
LIMIT 2,1
but with my current query I don't know how to make it...
Sample table
+----+------+------+-------+
| id | name | type | count |
+----+------+------+-------+
| 1 | a | 1 | 2 |
| 2 | ab | 1 | 3 |
| 3 | abc | 1 | 1 |
| 4 | b | 2 | 7 |
| 5 | ba | 2 | 1 |
| 6 | cab | 3 | 9 |
+----+------+------+-------+
I'm taking name for each type with max count with this query
SELECT
`table1b`.`name`
FROM
(SELECT
`table1a`.`type`, MAX(`table1a`.`count`) AS `Count`
FROM
`table1` AS `table1a`
GROUP BY `table1a`.`type`) AS `table1a`
INNER JOIN
`table1` AS `table1b` ON (`table1b`.`type` = `table1a`.`type` AND `table1b`.`count` = `table1a`.`Count`)
and I want one more column additional to name with value before max(count)
so result should be
+------+------------+
| name | before_max |
+------+------------+
| ab | 2 |
| b | 1 |
| cab | NULL |
+------+------------+
Please ask if something isn't clear ;)
AS per your given table(test) structure, the query has to be as follows :
select max_name.name,before_max.count
from
(SELECT type,max(count) as max
FROM `test`
group by type) as type_max
join
(select type,name,count
from test
) as max_name on (type_max.type = max_name.type and count = type_max.max )
left join
(select type,count
from test as t1
where count != (select max(count) from test as t2 where t1.type = t2.type)
group by type
order by count desc) as before_max on(type_max.type = before_max .type)