select non duplicates by column from select query [duplicate] - mysql

This question already has answers here:
SQL select only rows with max value on a column [duplicate]
(27 answers)
Group by minimum value in one field while selecting distinct rows
(10 answers)
Closed 4 years ago.
I've looked all over stackoverflow but without any luck, so here goes nothing.
I have a table populated with certain information on house positions, I select these positions and calculate the distance between the house coordinate and my desired coordinate, which I then order by distance ascending like so;
SELECT id, type, distance FROM (SELECT b.id, b.type, b.x, b.y, b.z,
SQRT(POWER(ABS(1654.5413 - b.x), 2) + POWER(ABS(-2293.7571 - b.y), 2) + POWER(ABS(-1.1996 - b.z), 2)) AS "distance"
FROM businesses b ORDER BY distance ASC) as T;
Example output;
+------+------+------------------------+
| id | type | distance |
+------+------+------------------------+
| 1953 | 2 | 0.00004489639611771451 |
| 2 | 100 | 8.757256937390904 |
| 1959 | 2 | 8.999959765646956 |
| 1960 | 2 | 10.499959765643807 |
| 1961 | 2 | 11.999959765641446 |
| 1962 | 2 | 13.499959765639607 |
| 1963 | 2 | 14.999959765638138 |
| 1964 | 2 | 16.499959765636934 |
| 2055 | 3 | 17.11486010149676 |
| 2054 | 1 | 17.751048488860313 |
| 1965 | 2 | 17.999959765635932 |
| 1966 | 2 | 19.499959765635083 |
| 1967 | 2 | 20.999959765634358 |
| 2056 | 5 | 22.26658275782834 |
| 1968 | 2 | 22.499959765633726 |
| 1969 | 2 | 23.999959765633175 |
| 2057 | 5 | 24.054132659013334 |
| 1970 | 2 | 25.49995976563269 |
| 2058 | 5 | 26.001138245767084 |
| 2061 | 4 | 26.853239370669378 |
| 1971 | 2 | 26.99995976563226 |
| 1972 | 2 | 28.49995976563187 |
| 2060 | 5 | 28.55999771765475 |
| 1973 | 2 | 29.999959765631523 |
| 2059 | 5 | 31.414688663981224 |
| 1974 | 2 | 31.499959765631207 |
| 1 | 100 | 121468.4587678613 |
+------+------+------------------------+
What I want to do with these results is only grab one row by selecting the non duplicates of the "type" column, like so (and keep the distance ASC order);
+------+------+------------------------+
| id | type | distance |
+------+------+------------------------+
| 1953 | 2 | 0.00004489639611771451 |
| 2 | 100 | 8.757256937390904 |
| 2055 | 3 | 17.11486010149676 |
| 2054 | 1 | 17.751048488860313 |
| 2056 | 5 | 22.26658275782834 |
| 2061 | 4 | 26.853239370669378 |
+------+------+------------------------+
If I attempt to "SELECT DISTINCT TYPE" it will not keep the order of the rows and will always select the last duplicate of "type" (I think I said that correctly).
How would I go about getting my desired result?

Related

Group by with categories created within the query in SQL

I have a table where I want to group by both categories and days, however I want to organize the days into separate buckets and apparently I do not find a way to do it.
Table:
| Days | Category | Values |
| 2 | A | 20 |
| 4 | B | 50 |
| 6 | A | 100 |
| 2 | A | 70 |
| 1 | B | 220 |
| 9 | A | 130 |
| 7 | A | 45 |
| 1 | A | 90 |
| 5 | B | 280 |
| 5 | B | 10 |
| 8 | A | 70 |
| 9 | B | 50 |
| 0 | A | 120 |
| 3 | B | 115 |
| 0 | B | 25 |
| 3 | B | 10 |
| 6 | A | 55 |
The result I would like to get:
| Days | Category | Values |
| 0-4 | A | 300 |
| 0-4 | B | 420 |
| 5-9 | A | 400 |
| 5-9 | B | 340 |
Based on my current knowledge this is how far I can get:
SELECT
Days, Category, Value
FROM
Table
GROUP BY
Days,
Category
But of course I cannot create the day buckets. Can you please help me out with it?
Use the DIV operator (DIV = Integer division. Discards from the division result any fractional part to the right of the decimal point):
SELECT CONCAT(
MIN(Days DIV 5) * 5,
' – ',
(MIN(Days DIV 5) + 1) * 5 - 1
) AS Days,
Category,
SUM(`Values`) AS `Values`
FROM `Table`
GROUP BY Days DIV 5,
Category
sqlfiddle

Mysql Finding Aggregate Between Two Other Values

I'm working with a pretty nasty table schema which unfortunately I can't change as it's defined by our SCADA program. There's one analog float value (power usage), and one digital int value (machine setting). I need to be able to find the Min, Max, and Avg of the power usage for each machine setting.
So basically each time a new machine setting (intvalue) is recorded, I need the aggregate power usage (floatvalue) until the next machine setting. I'd like to be able to group by intvalue as well, so I could get these aggregate numbers for a whole month, for example.
So far, I've tried playing around with joins and nested queries, but I can't get anything to work. I can't really find any examples like this either, since its such a poor table design.
Table schema found here: http://www.sqlfiddle.com/#!9/29164/1
Data:
| tagid | intvalue | floatvalue | t_stamp |
|-------|----------|------------|----------------------|
| 2 | 9 | (null) | 2019-07-01T00:01:58Z |
| 1 | (null) | 120.2 | 2019-07-01T00:02:00Z |
| 1 | (null) | 120.1 | 2019-07-01T00:02:31Z |
| 2 | 11 | (null) | 2019-07-01T00:07:58Z |
| 1 | (null) | 155.9 | 2019-07-01T00:08:00Z |
| 1 | (null) | 175.5 | 2019-07-01T00:10:12Z |
| 1 | (null) | 185.5 | 2019-07-01T00:10:58Z |
| 2 | 2 | (null) | 2019-07-01T00:11:22Z |
| 1 | (null) | 10.1 | 2019-07-01T00:11:22Z |
| 1 | (null) | 12 | 2019-07-01T00:13:58Z |
| 1 | (null) | 9.9 | 2019-07-01T00:14:21Z |
| 2 | 9 | (null) | 2019-07-01T00:15:38Z |
| 1 | (null) | 120.9 | 2019-07-01T00:15:39Z |
| 1 | (null) | 119.2 | 2019-07-01T00:16:22Z |
Desired output:
| intvalue | min | avg | max |
|----------|-------|-------|-------|
| 2 | 9.9 | 10.7 | 12 |
| 9 | 119.2 | 120.1 | 120.9 |
| 11 | 155.9 | 172.3 | 185.5 |
Is this possible?
You can fill the missing intvalues with a subquery in the SELECT clause:
select t.*, (
select t1.intvalue
from sqlt_data_1_2019_07 t1
where t1.t_stamp <= t.t_stamp
and t1.intvalue is not null
order by t1.t_stamp desc
limit 1
) as group_int
from sqlt_data_1_2019_07 t
order by t.t_stamp;
The result will be
| tagid | intvalue | floatvalue | t_stamp | group_int |
| ----- | -------- | ---------- | ------------------- | --------- |
| 2 | 9 | | 2019-07-01 00:01:58 | 9 |
| 1 | | 120.2 | 2019-07-01 00:02:00 | 9 |
| 1 | | 120.1 | 2019-07-01 00:02:31 | 9 |
| 2 | 11 | | 2019-07-01 00:07:58 | 11 |
| 1 | | 155.9 | 2019-07-01 00:08:00 | 11 |
| 1 | | 175.5 | 2019-07-01 00:10:12 | 11 |
| 1 | | 185.5 | 2019-07-01 00:10:58 | 11 |
| 2 | 2 | | 2019-07-01 00:11:22 | 2 |
| 1 | | 10.1 | 2019-07-01 00:11:22 | 2 |
| 1 | | 12 | 2019-07-01 00:13:58 | 2 |
| 1 | | 9.9 | 2019-07-01 00:14:21 | 2 |
| 2 | 9 | | 2019-07-01 00:15:38 | 9 |
| 1 | | 120.9 | 2019-07-01 00:15:39 | 9 |
| 1 | | 119.2 | 2019-07-01 00:16:22 | 9 |
Now you can simply group by the result of the subquery:
select (
select t1.intvalue
from sqlt_data_1_2019_07 t1
where t1.t_stamp <= t.t_stamp
and t1.intvalue is not null
order by t1.t_stamp desc
limit 1
) as group_int,
min(floatvalue) as min,
avg(floatvalue) as avg,
max(floatvalue) as max
from sqlt_data_1_2019_07 t
group by group_int
order by group_int;
And you get:
| group_int | min | avg | max |
| --------- | ----- | ------------------ | ----- |
| 2 | 9.9 | 10.666666666666666 | 12 |
| 9 | 119.2 | 120.10000000000001 | 120.9 |
| 11 | 155.9 | 172.29999999999998 | 185.5 |
View on DB Fiddle

How to query closest date and display the specific data

Hi guys i have a problem displaying a data from my query code.
I want to display a data from the closest date today. Below is my sample data and my output data that i want to display.
Landing Area data
|landing_id| id_number| address |
---------------------------------
| 1 | 00012345 | Ozamiz |
| 2 | 00012346 | Tudela |
| 3 | 00012347 | Nailon |
| 4 | 00012348 | Taboo |
| 5 | 00012349 | Jimenez |
| 6 | 00012350 | Tangub |
---------------------------------
Percentage data
|percent_id| landing_id | percentage | date_added |
-----------------------------------------------------------
| 1 | 1 | 9 |2018-10-08 21:42:22 |
| 2 | 1 | 12 |2018-10-03 20:43:32 |
| 3 | 1 | 43 |2018-10-15 19:43:49 |
| 4 | 3 | 22 |2018-10-10 15:43:56 |
| 5 | 3 | 77 |2018-10-12 18:44:03 |
-----------------------------------------------------------
And this is my query code.
SELECT fish_landing.landing_id,
percentage.landing_id as percentage_landing_id,
percentage.percentage,
percentage.date_added
FROM percentage
RIGHT OUTER JOIN fish_landing ON percentage.landing_id = fish_landing.landing_id
ORDER BY fish_landing.landing_id ASC
The output of my code is this, where the date_added and the percentage is not exact.
|percent_id| percentage | date_added |
----------------------------------------------
| 1 | 9 |2018-10-08 21:42:22 |
| 2 | | |
| 3 | 22 |2018-10-10 15:43:56 |
| 4 | | |
| 5 | | |
| 6 | | |
----------------------------------------------
And the output data that I want to display is the table below, where the percentage that has a latest date_added in every landing_id will be display.
|landing_id| percentage | date_added | address |
--------------------------------------------------------
| 1 | 43 |2018-10-15 19:43:49 | Ozamiz |
| 2 | | | |
| 3 | 77 |2018-10-12 18:44:03 | Nailon |
| 4 | | | |
| 5 | | | |
| 6 | | | |
--------------------------------------------------------
I hope you can help me in my problem.
You can get maximum date_added for a landing_id in a separate derived table and use it for joining.
Try the following:
SELECT fish_landing.landing_id,
percentage.percentage,
percentage.date_added,
fish_landing.address
FROM fish_landing
LEFT JOIN percentage ON percentage.landing_id = fish_landing.landing_id
LEFT JOIN (SELECT landing_id, MAX(date_added) AS max_date_added
FROM percentage
GROUP BY landing_id) AS dt
ON dt.landing_id = percentage.landing_id AND
dt.max_date_added = percentage.date_added
ORDER BY fish_landing.landing_id ASC

I want to ranking result with city based in mysql

I want to ranking result with city based in mysql
table1:-users
| user_id | marks |
--------------------
| 1 | 10 |
| 5 | 10 |
| 5 | 50 |
| 3 | 15 |
| 4 | 10 |
| 2 | 10 |
| 6 | 10 |
| 6 | 50 |
| 4 | 15 |
| 4 | 10 |
table:-2 users details
| user_id | city |
--------------------
| 1 | newdelhi |
| 2 | kolkata |
| 3 | mumbai |
| 4 | newdelhi |
| 5
| 6 | newdelhi |
I want to result like this:
| user_id | points |
--------------------
| 6 | 60 |
| 4 | 35 |
| 1 | 10 |
Try this :
SELECT
users.user_id
,SUM(users.marks) AS points
FROM
users
INNER JOIN
users_details ON users.user_id = users_details.user_id
WHERE
users_details.city = 'newdelhi'
GROUP BY
user_id

How to get count of combinations from database?

How to get count of combinations from database?
I have to database tables and want to get the count of combinations. Does anybody know how to put this in a database query, therefore I haven't a db request for each trip?
Trips
| ID | Driver | Date |
|----|--------|------------|
| 1 | A | 2015-12-15 |
| 2 | A | 2015-12-16 |
| 3 | B | 2015-12-17 |
| 4 | A | 2015-12-18 |
| 5 | A | 2015-12-19 |
Passengers
| ID | PassengerID | TripID |
|----|-------------|--------|
| 1 | B | 1 |
| 2 | C | 1 |
| 3 | D | 1 |
| 4 | B | 2 |
| 5 | D | 2 |
| 6 | A | 3 |
| 7 | B | 4 |
| 8 | D | 4 |
| 9 | B | 5 |
| 10 | C | 5 |
Expected result
| Driver | B-C-D | B-D | A | B-C |
|--------|-------|-----|---|-----|
| A | 1 | 2 | - | 1 |
| B | - | - | 1 | - |
Alternative
| Driver | Passengers | Count |
|--------|------------|-------|
| A | B-C-D | 1 |
| A | B-D | 2 |
| A | B-C | 1 |
| B | A | 1 |
Has anybody an idea?
Thanks a lot!
Try this:
SELECT Driver, Passengers, COUNT(*) AS `Count`
FROM (
SELECT t.ID, t.Driver,
GROUP_CONCAT(p.PassengerID
ORDER BY p.PassengerID
SEPARATOR '-') AS Passengers
FROM Trips AS t
INNER JOIN Passengers AS p ON t.ID = p.TripID
GROUP BY t.ID, t.Driver) AS t
GROUP BY Driver, Passengers
The above query will produce the alternative result set. The other result set can only be achieved using dynamic sql.
Demo here