I have a table with two columns of importance, customer ID# and timestamp. Whenever a customer orders something, five rows are created with the customer ID # and the timestamp of when it went through.
If there is more than five rows, it means our system hasn't processed the order correctly and there could be a problem, and I was asked to look through the log to find the customer IDs of any people who received more than 5, as well as how many times they received an incorrect amount and the number they received each time (when it was not 5)
I want it to show me, whenever the same customer ID (in column "ID") has more than 5 rows with the same timestamp (column "stamp") it will tell me 1. the person's customer ID 2. how many times this irregularity has happened to that customer ID, and 3. how many rows were in each irregularity (was it 6 or 7... or more? etc.) (if #2 was 3 times, I would like #3 to be an array like { 7, 8, 6 })
I don't know if this is possible... but any help at all will be appreciated. Thanks!
This should get you most of the way there:
SELECT `CustomerID`, `Timestamp`, COUNT(1)
FROM
OrderItems
GROUP BY
`CustomerID`, `Timestamp`
HAVING
COUNT(1) > 5
This will get you the IDs and Timestamps with more than 5 rows. I am making the assumption that the timestamps for all 5 (or more rows) are identical.
SELECT A.ID, A.TIMESTAMP
FROM "TABLE" A
WHERE
(SELECT COUNT(B.ID)
FROM "TABLE" B
WHERE B.ID = A.ID
AND B.TIMESTAMP = A.TIMESTAMP) > 5
Related
I will explain the logic:
I need to retrieve only the most recent room type/rate plan combinations from the rateplan_roomtypeTable.
room type ID and rate plan id are located in separate columns
there are 2 conditions that need to be met: all active room type/rate plan combinations need to be retrieved along with all room type/rate plan combinations that have produced even if they are not active. All these combinations need to be the most recent ones.
The desired results would be like the table I ll share with you:
Your help with the below query will be much appreciated:
select
Id
, RoomTypeId
, RateTypeId
,isactiveRateType
,isactiveRoomType
, RatePlanName
, RoomTypeName
FROM
rateplan_roomtypeTable
where
RateTypeId IN (select RateTypeId from ProductionTable where (cast(bookingdate as date) between date_add('day',-92, current_date) and date_add('day', -2, current_date)))
OR (isactiveRateType = 1 and isactiveRoomType = 1)
GROUP BY
1,2,3,4,5
Thank you
I already asked this question earlier but forgot a few (important) details or got them wrong.
My table in MySQL 8.0.29 looks like this
UserID
Appointment
Description
Bob
2022-06-01
Cleaning
Bob
2022-06-03
Toothache
John
2022-06-02
Braces
I'm trying to get the latest appointment for every person sorted by oldest first.
The query should return
UserID
Appointment
Description
John
2022-06-02
Braces
Bob
2022-06-03
Toothache
Using one of the previous answers I get
SELECT Name, Appointment, Description
FROM (
SELECT Name, Appointment, Description, ROW_NUMBER() OVER(PARTITION BY Name ORDER BY Appointment DESC) rn) t1
WHERE rn = 1
The problem is the database currently has 3 million rows and it'll continue to grow so this query ends up being pretty slow.
My plan is to consume the data in chunks so I'd prefer the query having "pagination". Something like a LIMIT 0, 5000 to get 5000 records at a time.
I'm open to even re-architecting the database if it comes to that.
For now i've resorted to creating a new table that just keeps the latest appointment for each user.
You are halfway there. Use that query as a 'derived table' instead of making it permanent:
SELECT b.*
FROM ( SELECT user_id, MAX(appointment) AS last_date)
FROM tbl
GROUP BY user_id ) AS x
JOIN tbl AS b ON b.user_id = x.user_id
AND b.appointment = x.last_date
And be sure to have INDEX(user_id, appointment)
I would be interested to see if this and the "OVER" approach both give the same results and which is faster.
I wonder if anyone could help with a MySQL query I am trying to write to return relevant results.
I have a big table of change log data, and I want to retrieve a number of record 'groups'. For example, in this case a group would be where two or more records are entered with the same timestamp.
Here is a sample table.
==============================================
ID DATA TIMESTAMP
==============================================
1 Some text 1379000000
2 Something 1379011111
3 More data 1379011111
3 Interesting data 1379022222
3 Fascinating text 1379033333
If I wanted the first two grouped sets, I could use LIMIT 0,2 but this would miss the third record. The ideal query would return three rows (as two rows have the same timestamp).
==============================================
ID DATA TIMESTAMP
==============================================
1 Some text 1379000000
2 Something 1379011111
3 More data 1379011111
Currently I've been using PHP to process the entire table, which mostly works, but for a table of 1000+ records, this is not very efficient on memory usage!
Many thanks in advance for any help you can give...
Get the timestamps for the filtering using a join. For instance, the following would make sure that the second timestamp is in a completed group:
select t.*
from t join
(select timestamp
from t
order by timestamp
limit 2
) tt
on t.timestamp = tt.timestamp;
The following would get the first three groups, no matter what their size:
select t.*
from t join
(select distinct timestamp
from t
order by timestamp
limit 3
) tt
on t.timestamp = tt.timestamp;
I have a mysql table like below
id trader price
111 abc 5
222 xyz 5.20
333 abc 5.70
444 xyz 5
555 abc 5.20
I need to compare row 1's price with row 2's price and accroding to the given sample row 2's price is less than row 1's price which means that trader xyz increased the price once, and in the same way when we compare row 2's price with row 3's price where row 3's price is higher than row 2's price which means trader abc also increased the price once. So in this manner I need to compare the entire table and find how many times each trader increased or decreased price...
I dont have any idea to do this, can someone please help me on this
You can perform a "self-join" (joining the table to itself) to perform queries. The tricky part here is knowing the order in which rows were inserted into the table, and only comparing rows that are sequentially (temporally) adjacent. I'm assuming you have some sort of TIMESTAMP column that will tell you which price changes came after the prior ones. If not, then perhaps "ID" can inform you of that (the greater ID row being inserted after the lesser ID).
Calling your table 'TAB', using 'TRADER' to provide the join, and using 'ID' to provide the Order, the query would require a three-way self-join such as follows:
SELECT a.trader
, SUM(IF(a.price > b.price, 1, 0)) nbr_incr
, SUM(IF(a.price < b.price, 1, 0)) nbr_decr
, SUM(IF(a.price = b.price, 1, 0)) nbr_same
FROM tab a
JOIN tab b
ON a.trader = b.trader AND a.id > b.id
LEFT OUTER JOIN tab c
ON a.trader = c.trader AND a.id > c.id AND b.id < c.id
WHERE c.id IS NULL
GROUP BY a.trader
The above query joins the table to itself twice so that each tab represents the following:
tab a : The more recent row for comparison
tab b : The immediately prior row to compare against
tab c : A row between a & b timewise (should not exist)
We perform a LEFT OUTER JOIN to 'tab c' because we do not actually want that row to exist. In the where clause, we filter our results only to the results where a 'tab c' row does not exist.
Finally, the query performs a 'GROUP BY' on the trader, and SUM()s the Increments and Decrements by comparing the price from the 'a' and 'b' rows.
This was a fun challenge. Hope this helps!
john...
You will need to setup a separate table if you want to track a history of price changes. Also, when you refer to columns, it sounds like you mean rows.
I've got a database table called servers with three columns 'id', 'name', and 'votes'.
How can I select the position of column id 5 by votes?
Example, I want to check which position server 3 is in by votes in my competition?
If I've interpreted your question correctly, you are asking how to find the rank of the row with id 5 in a list of servers sorted by votes. There is a complex solution, which requires sorting, but the easier solution which can be done in O(log(n)) space and O(n) time is to simply measure the number of votes for id = 5
select votes from servers where id = 5;
and then walk through the database and add one for every server encountered that has smaller number of votes. Alternatively, you can do something like:
select count(*) from servers where votes <= %votes
It is excessive to sort this (O(nlog(n) time) when you can simple iterate through the entire list once and gather all the information you need.
Use LIMIT:
SELECT id, name, votes FROM servers ORDER BY votes DESC LIMIT 2,1;
LIMIT a, b means "give me b rows, starting at row a", and a is zero-based.
OK, I misunderstood. Now. Suppose your server has 27 votes.
SELECT COUNT(*) FROM servers WHERE votes < 27;
Your server's rank will be 1 plus the result; ties are possible (i.e. ranks will be like 1, 2, 3, 3, 3, 6, 7, 7, 9 etc.).