Mysql results differs at evens from singles in same query - mysql

I have a strange error first time seing such results maybe someone else also found how to overpass such odd error.
I have a table structure like this :
|id|uid|test1|test2|rid|
1 1 - - 1
2 1 - - 1
3 2 - - 2
4 2 - - 2
5 3 - - 3
6 3 - - 3
7 4 - - 4
8 4 - - 4
----------------------------
as "-" are varchar data all other columns are integers
My query with the odd results is this :
SELECT COUNT(uid) AS COUNT,
id AS ID,
uid AS InqID,
test1 AS A,
test2 AS B
FROM test_table
WHERE rid = (X)
GROUP BY uid
ORDER BY id DESC
As results i get
if (X) = 1 or 3 it shows me the correct last id number (2 id for 1 and 6 id for 3)
but if (X) is 2 or 4 it shows me the first in row id number (3 id for 2 instead of 4 and 7 id for 4 instead of 8)
Can anyone tell me why i get the correct results only as singles in rid and not at even numbers of rid column or how at least this query will work as it has to ?
Thank you all in advance

Use MAX(id) instead of ORDER BY.
SELECT COUNT(uid) AS COUNT, MAX(id) AS ID, uid AS InqID, test1 AS A, test2 AS B
FROM test_table
WHERE rid = (X)
GROUP BY uid

Related

MySQL Group by consecutive values and count

I have a table that looks like this
id
1
2
4
5
6
10
11
So a bunch of consecutive values, an unknown number of absent fields and then other consecutive values.
What I am trying to achieve is to get
id
stint
1
0
2
0
4
1
5
1
6
1
10
2
11
2
By incrementing every time the number of the stint, which I can later use for summing over other columns.
Is it possible? Thanks
If your MySQL version support window function.
You can try to use LAG window function in subquery to get previous id column, then use SUM condition aggregate window function.
Query #1
SELECT Id,
SUM(id - n_Id > 1) OVER(ORDER BY id) stint
FROM (
SELECT *,LAG(id,1,id) OVER(ORDER BY id) n_Id
FROM T
) t1
Id
stint
1
0
2
0
4
1
5
1
6
1
10
2
11
2
View on DB Fiddle

SQL - Max value from a group by when creating a new field

I have a database with a table called BOOKINGS containing the following values
main-id place-id start-date end-date
1 1 2018-8-1 2018-8-8
2 2 2018-6-6 2018-6-9
3 3 2018-5-5 2018-5-8
4 4 2018-4-4 2018-4-5
5 5 2018-3-3 2018-3-10
5 1 2018-1-1 2018-1-6
4 2 2018-2-1 2018-2-10
3 3 2018-3-1 2018-3-28
2 4 2018-4-1 2018-4-6
1 5 2018-5-1 2018-5-15
1 3 2018-6-1 2018-8-8
1 4 2018-7-1 2018-7-6
1 1 2018-8-1 2018-8-18
1 2 2018-9-1 2018-9-3
1 5 2018-10-1 2018-10-6
2 5 2018-11-1 2018-11-5
2 3 2018-12-1 2018-12-25
2 2 2018-2-2 2018-2-19
2 4 2018-4-4 2018-4-9
2 1 2018-5-5 2018-5-23
What I need to do is for each main-id I need to find the largest total number of days for every place-id. Basically, I need to determine where each main-id has spend the most time.
This information must then be put into a view, so unfortunately I can't use temporary tables.
The query that gets me the closest is
CREATE VIEW `MOSTTIME` (`main-id`,`place-id`,`total`) AS
SELECT `BOOKINGS`.`main-id`, `BOOKINGS`.`place-id`, SUM(DATEDIFF(`end-date`, `begin-date`)) AS `total`
FROM `BOOKINGS`
GROUP BY `BOOKINGS`.`main-id`,`RESERVATION`.`place-id`
Which yields:
main-id place-id total
1 1 24
1 2 18
1 5 5
2 1 2
2 2 20
2 4 9
3 1 68
3 2 24
3 3 30
4 1 5
4 2 10
4 4 1
5 1 19
5 2 4
5 5 7
What I need is then the max total for each distinct main-id:
main-id place-id total
1 1 24
2 2 20
3 1 68
4 2 10
5 1 19
I've dug through a large amount of similar posts that recommend things like self joins; however, due to the fact that I have to create the new field total using an aggregate function (SUM) and another function (DATEDIFF) rather than just querying an existing field, my attempts at implementing those solutions have been unsuccessful.
I am hoping that my query that got me close will only require a small modification to get the correct solution.
Having hyphen character - in column name (which is also minus operator) is a really bad idea. Do consider replacing it with underscore character _.
One possible way is to use Derived Tables. One Derived Table is used to determine the total on a group of main id and place id. Another Derived Table is used to get maximum value out of them based on main id. We can then join back to get only the row corresponding to the maximum value.
CREATE VIEW `MOSTTIME` (`main-id`,`place-id`,`total`) AS
SELECT b1.main_id, b1.place_id, b1.total
FROM
(
SELECT `main-id` AS main_id,
`place-id` AS place_id,
SUM(DATEDIFF(`end-date`, `begin-date`)) AS total
FROM BOOKINGS
GROUP BY main_id, place_id
) AS b1
JOIN
(
SELECT dt.main_id, MAX(dt.total) AS max_total
FROM
(
SELECT `main-id` AS main_id,
`place-id` AS place_id,
SUM(DATEDIFF(`end-date`, `begin-date`)) AS total
FROM BOOKINGS
GROUP BY main_id, place_id
) AS dt
GROUP BY dt.main_id
) AS b2
ON b1.main_id = b2.main_id AND
b1.total = b2.max_total
MySQL 8+ solution would be utilizing the Row_Number() functionality:
CREATE VIEW `MOSTTIME` (`main-id`,`place-id`,`total`) AS
SELECT b.main_id, b.place_id, b.total
FROM
(
SELECT dt.main_id,
dt.place_id,
dt.total
ROW_NUMBER() OVER (PARTITION BY dt.main_id
ORDER BY dt.total DESC) AS row_num
FROM
(
SELECT `main-id` AS main_id,
`place-id` AS place_id,
SUM(DATEDIFF(`end-date`, `begin-date`)) AS total
FROM BOOKINGS
GROUP BY main_id, place_id
) AS dt
GROUP BY dt.main_id
) AS b
WHERE b.row_num = 1

Identify consecutive rows

I have a table in the following format:
cId seq
--- ---
A 1
A 2
A 4
A 5
B 8
B 9
A 12
A 13
I would like to write a query that would produce another table that looks like:
cId seq consecutive
--- --- -----------
A 1 1
A 2 1
A 4 2
A 5 2
B 8 3
B 9 3
A 12 4
A 13 4
What I am trying to do is identify consecutive seq values that have the same cId and then number them.
I was thinking of using Lag function to determine the previous seq value and then setting the consecutive column but don't know how to increment the value when I encounter the next break.
SELECT [cId],
[Seq],
CASE WHEN [Seq] - 1 = LAG([Seq], 1, [Seq]) OVER ( ORDER BY [Seq]) THEN 1
ELSE 2 END as consecutive
FROM #ConsecutiveData
This query will put a 2 next to the start of each sequence. That's the closest I have come.
I think author is not using MySQL, since, as far as I know, there is no LAG function in MySQL.
Below is a possible solution for MSSQL:
SELECT
cid,
seq,
DENSE_RANK() OVER (ORDER BY seq - row_num) consecutive
FROM (
SELECT
cid,
seq,
ROW_NUMBER() OVER (ORDER BY seq) row_num
FROM
test_table
) data
;
Check at SQLFiddle: SQLFiddle Example

SQL Ordering Data from row "n+1" to "n-1"

I have a simple question. In MySQL, consider a row "n", how can we order rows by id (for example), but start from the row "n+1" and end to the row "n-1" ?
Thanks !
EDIT : I ommit to precise that I seek the query in MySQL.
From an answer below, here an example :
ID
---
1
2
3
4 <--N
5
6
I want Desired Results ordered as follows
5 <--N + 1
6
1
2
3 <--N - 1
So you mean. For a table
ID
---
1
2
3
4 <--N
5
6
You want Desired Results ordered as follows?
5 <--N + 1
6
1
2
3 <--N - 1
If so
SELECT ID
FROM T
WHERE ID <> 4
ORDER BY CASE WHEN ID > 4 THEN 0 ELSE 1 END, ID
Assuming table MyTable with integer column N:
SELECT *
from MyTable
where Id between N-1 and N+1
order by N desc
You're asking how to sort by descending ?
Just stick
ORDER BY col a , col b DESC;
at the end

Access Totals Query Not Necessarily Returning First Record

I have a table of data like this:
id user_id A B C
=====================
1 15 1 2 3
2 15 1 2 5
3 20 1 3 9
4 20 1 3 7
I need to remove duplicate user ids and keep the record that sorts lowest when sorting by A then B then C. So using the above table, I set up a temp query (qry_temp) that simply does the sort--first on user_id, then on A, then on B, then on C. It returns the following:
id user_id A B C
====================
1 15 1 2 3
2 15 1 2 5
4 20 1 3 7
3 20 1 3 9
Then I wrote a Totals Query based on qry_temp that just had user_id (Group By) and then id (First), and I assumed this would return the following:
user_id id
===========
15 1
20 4
But it doesn't seem to do that--instead it appears to be just returning the lowest id in a group of duplicate user ids (so I get 1 and 3 instead of 1 and 4). Shouldn't the Totals query use the order of the query it's based upon? Is there a property setting in the query that might impact this or another way to get what I need? If it helps, here is the SQL:
SELECT qry_temp.user_id, First(qry_temp.ID) AS FirstOfID
FROM qry_temp
GROUP BY qry_temp.user_id;
You need a different type of query, for example:
SELECT tmp.id,
tmp.user_id,
tmp.a,
tmp.b,
tmp.c
FROM tmp
WHERE (( ( tmp.id ) IN (SELECT TOP 1 id
FROM tmp t
WHERE t.user_id = tmp.user_id
ORDER BY t.a,
t.b,
t.c,
t.id) ));
Where tmp is the name of your table. First, Last, Min and Max are not dependent on a sort order. In relational databases, sort orders are quite ephemeral.