Summarize the Problem:
I cannot get ORDER BY DESC to work.
The column that I'm trying to order is DATETIME so I should not have to do a conversion, I don't think.
Describe what you've tried:
The NULL value is the one I want to fill in with the most recent datetime from a different table
Table Image. I am able to fill in a time, but the time is not the most recent pilot_death for this pilotID #. I am not able to do ORDER BY on the datetime.
Note: Since this is complicated enough for me, I have provided the data tables in an sql query in the mediafire link here: https://www.mediafire.com/file/owucp67djcc8djp/pilot_stats.sql/file
fiddle.
Before:
Code:
$sql = 'UPDATE pe_DeathAncestoryFinal
SET pe_DeathAncestoryFinal_lastpilotdeathtime = (
SELECT DISTINCT pe_LogEvent_datetime
FROM pe_LogEvent
WHERE pe_DeathAncestoryFinal_pilotid = pe_LogEvent_pilotid AND pe_LogEvent_type =
"pilot_death"
GROUP BY pe_DeathAncestoryFinal_pilotname
ORDER BY pe_LogEvent_datetime DESC )
WHERE pe_DeathAncestoryFinal_lastpilotdeathtime IS NULL
';
After: I want this date in there -> 2021-04-10 19:36:02
UPDATE pe_deathancestoryfinal
JOIN ( SELECT pe_LogEvent_pilotid,
MAX(pe_LogEvent_datetime) pe_LogEvent_datetime
FROM pe_logevent
WHERE pe_LogEvent_type = "pilot_death"
GROUP BY pe_LogEvent_pilotid ) x ON pe_DeathAncestoryFinal_pilotid = pe_LogEvent_pilotid
SET pe_DeathAncestoryFinal_lastpilotdeathtime = pe_LogEvent_datetime
WHERE pe_DeathAncestoryFinal_lastpilotdeathtime IS NULL
https://dbfiddle.uk/?rdbms=mysql_8.0&fiddle=f4866412b4d46b6ec120fbd0b70939ce
Related
I have about 5 million records in a database table (MySQL 5.6), and I wanted to get the last 2 dates, grouped by ID. Looking around the web, I found examples that allowed me to cobble together the following...
SELECT id, date
FROM
(
SELECT *,
#id_rank := IF(#current_id = id, #id_rank + 1, 1) AS id_rank,
#current_id := id
FROM `data`
ORDER BY id DESC, date DESC
) ranked
WHERE id_rank <= 2
ORDER BY id ASC, date DESC
Running this code from MySQL Workbench, returned 5,700 rows, which is what I expected. I then tried to call this SQL as-is from PHP, using the following SQL string...
$subSql =
"SELECT *, " .
" #id_rank := IF(#current_id = id, #id_rank + 1, 1) AS id_rank, " .
" #current_id := id " .
"FROM `data` " .
"ORDER BY id DESC, date DESC";
$sql =
"SELECT id, date " .
"FROM ($subSql) ranked " .
"WHERE id_rank <= 2 " .
"ORDER BY id ASC, date DESC";
However, running this code resulted in out-of-memory. I them modified the code to return a count of the number of records expected, and instead of the expected 5,700 rows, it returned 4,925,479. So my question is "what do I have to change in my PHP SQL above, to get the correct results that I was getting from MySQL Workbench".
Assigning variables in MySQL has been deprecated. You should be using window functions:
SELECT id, date
FROM (SELECT d.*,
ROW_NUMBER() OVER (PARTITION BY id ORDER BY date DESC) as id_rank
FROM `data` d
) d
WHERE id_rank <= 2
ORDER BY id ASC, date DESC;
Even in older versions your code is not guaranteed to work because MySQL does not guarantee the order of evaluation of expressions. You are assigning the variable in one expression and using it in another -- and those can go in either order.
If your dates are unique per id, you can do this without variables:
select id, date
from (select d.*,
(select d2.date
from data d2
where d2.id = d.id and d2.date >= d.date
order by d2.date desc
limit 1 offset 1
) as date_2
from data d
) d
where date >= date_2 or date_2 is null;
For performance, you want an index on data(id, date).
I currently have the following tables with:
TABLE klusbonnen_deelnemers:
bonnummer (varchar) - order number
adres (varchar) - order adres
deelnemer (varchar) - user
binnen (date) - date order received
klaar (date) - original order milestone
datum_gereed (date) - date order completed
gereed (varchar) - YES or NO (YES= completed NO= Not yet completed)
datum_factuur (date) - date when user marked order completed (button clicked)
factuur (varchar) - weeknumber order completed
One order(bonnummer) can have multiple users (deelnemer) who all have to mark the order "completed" (datum_gereed). Only when ALL users (deelnemer) have marked an order (bonnummer) "completed" (datum_gereed) the order IS "completed".
I am trying to write a query that gives me:
All completed orders (bonnummer) in a given timespan (last month).
However...
The completion date (datum_gereed) should hold the LAST date (as that is the actual total completion date).
The list should have the Order (bonnummer) with the latest "marked completed" date (datum_factuur) on top (sort DESC) (of course only when all users (deelnemer) have completed the order (all users(deelnemers) having gereed="YES")
So far i have this:
SELECT DISTINCT tbl1.bonnummer AS 'KLUSBONNUMMER', tbl1.adres AS 'ADRES',
tbl1.binnen AS 'BINNENGEKOMEN OP', tbl1.klaar AS 'ORIGINELE STREEFDATUM',
tbl1.datum_gereed AS 'GEREEDGEKOMEN OP', tbl1.factuur AS 'WEEKNUMMER'
FROM klusbonnen_deelnemers AS tbl1
INNER JOIN
( SELECT tbl2.bonnummer
FROM klusbonnen_deelnemers AS tbl2
WHERE tbl2.bonnummer NOT IN (
SELECT tbl3.bonnummer
FROM klusbonnen_deelnemers AS tbl3
WHERE tbl3.gereed = 'NEE')
) AS tbl4 ON tbl1.bonnummer = tbl4.bonnummer
INNER JOIN
( SELECT bonnummer, MAX(datum_gereed) AS 'MAXDATUM'
FROM klusbonnen_deelnemers
GROUP BY bonnummer
) MAXFILTER ON tbl1.bonnummer = MAXFILTER.bonnummer
AND tbl1.datum_gereed = MAXFILTER.MAXDATUM
WHERE tbl1.datum_factuur BETWEEN NOW() - INTERVAL 2 MONTH AND NOW()
ORDER BY tbl1.bonnummer DESC
This query DOES work, however i think this can be done in a much simpler way.
On top of that the query only works in my navicat editor. Calling this query on my "live" website gives an error (subquery in WHERE clause...) (i do have all login correct as other queries DO work).
Anyone out there who can help (simplify) this query? Thx...
this part:
INNER JOIN (SELECT tbl2.bonnummer
FROM klusbonnen_deelnemers AS tbl2
WHERE tbl2.bonnummer NOT IN
(SELECT tbl3.bonnummer
FROM klusbonnen_deelnemers AS tbl3
WHERE tbl3.gereed = 'NEE')) AS tbl4
ON tbl1.bonnummer = tbl4.bonnummer
seems like useless. try to use gereed <> 'NEE' in the "very-bottom"-WHERE
SELECT DISTINCT
kd.bonnummer AS 'KLUSBONNUMMER',
kd.adres AS 'ADRES',
kd.binnen AS 'BINNENGEKOMEN OP',
kd.klaar AS 'ORIGINELE STREEFDATUM',
kd.datum_gereed AS 'GEREEDGEKOMEN OP',
kd.factuur AS 'WEEKNUMMER'
FROM klusbonnen_deelnemers AS kd
INNER JOIN (
SELECT bonnummer, MAX(datum_gereed) AS 'MAXDATUM'
FROM klusbonnen_deelnemers
GROUP BY bonnummer
) AS MAXFILTER
ON (kd.bonnummer = MAXFILTER.bonnummer AND kd.datum_gereed = MAXFILTER.MAXDATUM)
WHERE
kd.gereed <> 'NEE'
kd.datum_factuur BETWEEN NOW() - INTERVAL 2 MONTH AND NOW()
ORDER BY
kd.bonnummer DESC
I have a database table 'sales_list'. In this is rows of sales records attributed to a users_sales_guild_id. I'd like to query the table and order results by the number of sales made by each user, highest to lowest.
I thought this query would do it, but alas no...
$total_query = "SELECT *, COUNT(users_sales_guild_id) AS users_sales_guild_id_count FROM sales_list WHERE sales_entry_date BETWEEN '2013-10-01 00:00:00' AND '2014-11-30 23:59:59' ORDER BY users_sales_guild_id_count DESC";
$total_rs = mysql_query($total_query) or trigger_error ("Query: $total_query\n<br>MySQL Error: " .#mysql_error()); // Run the query.
$num_rs = mysql_num_rows($total_rs);
This query returns 1 record. rather than a selection of records ordered by the number of sales by each user.
Your assistance is much welcomed.
count(*) will return one row unless there is a group by clause, so the query should be as
SELECT *,
COUNT(*) AS users_sales_guild_id_count
FROM sales_list
WHERE sales_entry_date BETWEEN '2013-10-01 00:00:00' AND '2014-11-30 23:59:59'
group by users_sales_guild_id
ORDER BY users_sales_guild_id_count DESC
UPDATE : Its better to select col1,col2 ..... instead of * while doing group by - Point raised by InoSHeo
check this link
http://sqlfiddle.com/#!2/1201d/6
check this link if you would like to get details based on username http://sqlfiddle.com/#!2/1201d/4 here i have used type instead you can use username
I have a table in which subscription_id is used multiple times, every month a customer charged an order to be generated with same data & unique order id so there is a column 'updated_at' which also updates so I want to get only one (1) latest record from table based on subscription_id, I am using following query, but it's not working and getting old record.
SELECT *
FROM members_subscriptions
WHERE status = 'active'
GROUP BY subscription_id
ORDER BY updated_at DESC
Can any one tell me what's wrong with this query ....
You need get the MAX() of updated_at , order by runs after grouping so you need to compare with the newest date
SELECT DISTINCT *
FROM members_subscriptions
WHERE status = 'active'
AND updated_at IN(
SELECT MAX(updated_at)
FROM members_subscriptions
GROUP BY subscription_id
)
ORDER BY updated_at DESC
or
SELECT DISTINCT m.*
FROM members_subscriptions m
INNER JOIN (
SELECT subscription_id, MAX(updated_at) AS updated_at
FROM members_subscriptions GROUP BY subscription_id
) AS maxdatte USING (subscription_id, updated_at);
Assumming that each subsciption can have only unique dates in updated_at, then this query should give desired result:
SELECT *
FROM members_subscriptions
WHERE status = 'active'
AND (subscription_id, updated_at) IN(
SELECT subscription_id, MAX(updated_at)
FROM members_subscriptions
GROUP BY subscription_id
)
ORDER BY updated_at DESC
But if one subscription may have more that one same dates, then the query must use unique id to get only one record from two or more with the same date:
SELECT *
FROM members_subscriptions m
WHERE status = 'active'
AND id = (
SELECT id FROM members_subscriptions m1
WHERE m.subscription_id = m1.subscription_id
AND status = 'active'
ORDER BY updated_at DESC
LIMIT 1
)
SELECT distinct (name)
FROM members_subscriptions
WHERE status = 'active'
GROUP BY subscription_id
ORDER BY updated_at DESC
use distinct with field name you want to find
The problem with your query is that result is first being grouped and only then ordered. If you need latest result, you need to do something like this:
SELECT *
FROM members_subscriptions as main
WHERE status = `active` AND `updated_at` = (
SELECT MAX(`updated_at`) FROM members_subscriptions as sub
WHERE status='active' and main.`subscription_id` = sub.`subscription_id`
)
Here's the situation:
In my database i have a table with threads, and a table with replies. Both have a Timestamp field.
Now i am developing a forum and wish to order threads in the following manner:
If the thread has replies, then: ORDER BY tblReply.Timestamp DESC
Else, the thread has no replies: ORDER BY tblThread.Timestamp DESC
I do not know how to combine these 2 in one statement.
My query as it is now:
SELECT `PK_ThreadID`, `Title`, `tblUsers`.`Username`, `tblThread`.`Date`, count(tblReply.FK_ThreadID) AS number_replies FROM (`tblThread`)
JOIN `tblUsers` ON `tblUsers`.`PK_UserID` = `tblThread`.`FK_UserID`
LEFT JOIN `tblReply` ON `tblReply`.`FK_ThreadID` = `tblThread`.`PK_ThreadID`
WHERE `isExpertQuestion` = 0 AND `isPublic` = 1
GROUP BY `PK_ThreadID`
ORDER BY max(tblReply.Date)` desc
//Here it only orders by reply date, so threads with no replies appear at the bottom
How do i achieve the ordering i want in this query?
Like this probably:
SELECT `PK_ThreadID`, `Title`,
`tblUsers`.`Username`,
`tblThread`.`Date`,
count(tblReply.FK_ThreadID) AS number_replies
FROM (`tblThread`)
JOIN `tblUsers` ON `tblUsers`.`PK_UserID` = `tblThread`.`FK_UserID`
LEFT JOIN `tblReply` ON `tblReply`.`FK_ThreadID` = `tblThread`.`PK_ThreadID`
WHERE `isExpertQuestion` = 0 AND `isPublic` = 1
GROUP BY `PK_ThreadID`
ORDER BY
CASE WHEN COUNT(tblReply.FK_ThreadID) > 0 THEN tblReply.Timestamp
WHEN COUNT(tblReply.FK_ThreadID) = 0 OR tblReply.FK_ThreadID IS NULL
THEN tblThread.Timestamp
END DESC