Fetch MySQL rows + one before condition - mysql

I have a time log table where all entries are entered with a time stamp and an event.
Now I want to select all the rows after a specific event AND ONE row before(ORDER BY time_stamp) that event.
I can easily achieve this with multiple queries, but is it possible with only one query ?
Using multiple queries
SELECT time
FROM table
WHERE event LIKE '%event_to_fint%'
SELECT event
FROM table
WHERE time<'time from last query'
LIMIT 1
ORDER BY
time DESC

One option is to
Use a regular select to select the time records you need.
Union this result with a select that retrieves the maximum time where this maximum time is less than the minimum time from your regular select.
SQL Statement
SELECT time
FROM table
WHERE event LIKE '%event_to_fint%'
UNION ALL
SELECT MAX(time)
FROM table
WHERE time < (
SELECT MIN(time)
FROM table
WHERE event LIKE '%event_to_fint%'
)

This solution in not too nice, but works:
SELECT *
FROM table
WHERE <condition_A>
ORDER BY <condition_B>
LIMIT (SELECT COUNT(*)
FROM table
WHERE <condition_A>
)+1

Related

How to select records with a count >30?

So I have this data set (down below) and I'm simply trying to gather all data based on records in field 1 that have a count of more than 30 (meaning a distinct brand that has 30+ record entries) that's it lol!
I've been trying a lot of different distinct, count esc type of queries but I'm falling short. Any help is appreciated :)
Data Set
By using GROUP BY and HAVING you can achieve this. To select more columns remember to add them to the GROUP BY clause as well.
SELECT Mens_Brand FROM your_table
WHERE Mens_Brand IN (SELECT Mens_Brand
FROM your_table
GROUP BY Mens_Brand
HAVING COUNT(Mens_Brand)>=30)
You can simply use a window function (requires mysql 8 or mariadb 10.2) for this:
select Mens_Brand, Mens_Price, Shoe_Condition, Currency, PK
from (
select Mens_Brand, Mens_Price, Shoe_Condition, Currency, PK, count(1) over (partition by Mens_Brand) brand_count
from your_table
) counted where brand_count >= 30

SQL query - union on NOW()

I tried making a SQL query and union the result on the current time, but I cannot seem to find a neat way to solve this.
I've tried the following:
SELECT * FROM `accounts`
UNION SELECT NOW()
And Sequel Pro just reports The used SELECT statements have a different number of columns.
The accountstable just has three columns:
ID (INT(32), AUTO_INC)
CREATED (Timestamp)
NAME (VAR_CHAR(28))
I anticipated I'd get a response with four columns: ID, CREATED, NAME, NOW
What do I do wrong?
Union means that the records from the second query will be appended to those retrieved from the first one.
So the two tables must have the same structure for this to work.
For example:
SELECT field1,field2,field3 FROM tableA
UNION
SELECT field1,field2,field3 FROM tableB
What you want to do is
SELECT *, NOW() as now FROM `accounts`
This will retrieve all the records from the accounts table and will add the timestamp to all the rows on a column named "now" (this is just an alias so use whatever you like).
try this
SELECT *,now() as now FROM `accounts`

SQL MIN() selecting Data. ORDER table correctly

I have 2 questions. First of all I have a MySQL Database with the rows: id(AUTO_INCREMENT PRIMARY KEY), name and time. This database represents the times of a race. I would like to select the name and time where the time is the smallest.
SELECT name, MIN(time) as time FROM race GROUP BY TIME;
This query gives me all times and names as long as there are no duplicates in the names. I however only want the fastest time and the name in that row.
Then when I submit my time i would like to know on what place I am. Will ORDER BY TIME keep each ID of each row the same or can I just ORDER table BY time and then select row where ID= 1?
If it's possible to have multiple entries with the same time, I would use a nested query like this, because limiting the result set to 1 may exclude a name.
select name, time from race where time = (select min(time) from race)
If you want to know what place a given time is in, just count the number of entries that have times less than it.
select count(*) + 1 as place from race where time < [your time]
For your first question, what you want is to select the 'least' time.
Here is, what I think, the clearest way to do that, which uses the LIMIT function to only return 1 row.
MySQL:
SELECT name, time
FROM race
ORDER BY time asc
LIMIT 1;
MS SQL:
SELECT TOP 1 name, time
FROM race
ORDER BY time asc

Order By on date field starting in a middle point of the dates range

I have a table "A" with a "date" field. I want to make a select query and order the rows with previous dates in a descending order, and then, the rows with next dates in ascending order, all in the same query. Is it possible?
For example, table "A":
id date
---------------------
a march-20
b march-21
c march-22
d march-23
e march-24
I'd like to get, having as a starting date "march-22", this result:
id date
---------------------
c march-22
b march-21
a march-20
d march-23
e march-24
In one query, because I'm doing it with two of them and it's slow, because the only difference is the sorting, and the joins I have to do are a bit "heavy".
Thanks a lot.
You could use something like this -
SELECT *
FROM test
ORDER BY IF(
date <= '2012-03-22',
DATEDIFF('2000-01-01', date),
DATEDIFF(date, '2000-01-01')
);
Here is a link to a test on SQL Fiddle - http://sqlfiddle.com/#!2/31a3f/13
That's wrong, sorry :(
From documentation:
However, use of ORDER BY for individual SELECT statements implies nothing about the order in which the rows appear in the final result because UNION by default produces an unordered set of rows. Therefore, the use of ORDER BY in this context is typically in conjunction with LIMIT, so that it is used to determine the subset of the selected rows to retrieve for the SELECT, even though it does not necessarily affect the order of those rows in the final UNION result. If ORDER BY appears without LIMIT in a SELECT, it is optimized away because it will have no effect anyway.
This should do the trick. I'm not 100% sure about adding an order in a UNION...
SELECT * FROM A where date <= now() ORDER BY date DESC
UNION SELECT * FROM A where date > now() ORDER BY date ASC
I think the real question here is how to do the joining once. Create a temporary table with the result of joining, and make the 2 selects from that table. So it will be be time consuming only on creation (once) not on select query (twice).
CREATE TABLE tmp SELECT ... JOIN -- do the heavy duty here
With this you can make the two select statenets as you originally did.

How to merge this two query statement into one query statement

1. SELECT * FROM instalmentsdetails WHERE instalmentName='Third Installment'AND studentFeeId='1'
2. select max(`receiptNo`)as `receiptNo` FROM instalmentsdetails
Table instalmentsdetails
instalmentsDetailsId
studentFeeId
receiptNo
instalmentName
amount
dueDate
fineAmt
waivedAmt
scholarShip
grandTotal
status
Little confused .How to merge this two query statement into one query statement
P.S: One statement checks for the condition and the other checks for the max of receiptNo in that table
I want both the values in one query
Is this what you want?
SELECT max(`receiptNo`) as `receiptNo`
FROM instalmentsdetails
WHERE instalmentName='Third Installment' AND studentFeeId='1'
Update: how about this:
SELECT *
FROM instalmentsdetails as inds
INNER JOIN (
SELECT max(`receiptNo`) as `maxreceiptNo`
FROM instalmentsdetails
) as maxt
WHERE inds.instalmentName='Third Installment' AND inds.studentFeeId='1'
This applies the filter to the table, then adds an extra column (the maximum receiptNo)
Assuming the goal is to get:
a list of instalmentsdetails with specific a instalmentName and studentFeeId
global maximum
 
SELECT *, 0 AS receiptNo FROM instalmentsdetails WHERE instalmentName='Third Installment'AND studentFeeId='1'
UNION
select *, max(`receiptNo`) as `receiptNo` FROM instalmentsdetails
Update
Apparently the OP simply wants to consolidate separate query results into a single row. In that case:
SELECT
*,
(SELECT max(`receiptNo`) FROM instalmentsdetails) AS maxReceiptNo
FROM instalmentsdetails WHERE instalmentName='Third Installment'AND studentFeeId='1'
From all the reading, Matt is correct, but maybe I can help explain what he's doing...
The first part of the query (From InstalmentsDetails WHERE YourCondition) will get all records that qualify for the condition.
THEN, by doing a JOIN to the second query (select max( 'receiptNo' ) from... with no where clause ) will ALWAYS return a single row, single column of the maximum receipt without regard to ANY criteria.
This creates an implied Cartesian result. Join everything in the first table with every record in the second. Since there is no explicit join condition, every row will get the same "max()" value as a returned column. And since there will only be one record in the select max() call, you never worry about duplicates.
Now, if you wanted the maximum receipt within the same criteria, you would just copy that same criteria to the select max() query portion.