I have this table:
CREATE TABLE tickets (
id INT UNSIGNED AUTO_INCREMENT PRIMARY KEY,
topic VARCHAR(64) NOT NULL,
priority TINYINT NOT NULL default 1,
created DATETIME);
INSERT INTO tickets (id, topic, priority, created) VALUES
(1, 'kin23oi5n2', 3, '2018-05-27 16:00:54'),
(2, 'ewbrv32b3', 2, '2018-05-27 16:00:54'),
(3, 'aern23523', 1, '2018-05-27 16:01:15'),
(4, '4bt43t3', 5, '2018-05-27 16:01:15'),
(5, '32n523n5235n235t3n4', 4, '2018-05-27 16:01:39'),
(6, 'e2nr2n23n5235n23n523', 3, '2018-05-27 16:01:39');
I'm running a query:
SELECT * FROM `tickets` order by `priority` ASC, `created` desc;
How do I get the row number with id 5 in this result using sql?
update:
SELECT count(*) as pos FROMticketsWHERE ...;
As a result, we obtain pos
I try to make that my result was similar to this but contained number of a line of the necessary row(id 5 for example).
in other words I want to get the number of the queue entry
If someone is interested, here is the answer
SELECT num FROM
(SET #row_number = 0;
SELECT
(#row_number:=#row_number + 1) AS num, id
FROM
tickets order by `priority` ASC, `created` desc) as tmp_table WHERE id = 6;
But now there was another question. How is this implemented in Larabel 5.6?
UP
And he did it.
Related
The query below gives me one record per day for each user. How can I modify it so that it gives me the earliest record per day for each user?
I tried using MIN() on the date field in the GROUP BY part, but that obviously doesn't work. There's a date_trunc function mentioned in this answer which seems to do what I want, but it is not available in MySQL. What's the best way to go about this?
For the sample data below, the query should return records with ids 1, 3, 5, and 7.
SELECT user_id, coords, date
FROM table
WHERE draft = 0
GROUP BY user_id, DAY('date')
CREATE TABLE `table` (
`id` bigint(20) UNSIGNED NOT NULL,
`user_id` int(11) NOT NULL,
`coords` point NOT NULL,
`date` datetime NOT NULL,
`draft` tinyint(4) NOT NULL DEFAULT 0
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
INSERT INTO `table` (`id`, `user_id`, `coords`, `date`, `draft`) VALUES
(1, 1, xxx, '2020-11-08 18:01:47', 0),
(2, 1, xxx, '2020-11-08 18:05:47', 0),
(3, 1, xxx, '2020-11-09 18:06:47', 0),
(4, 1, xxx, '2020-11-09 18:07:47', 0),
(5, 2, xxx, '2020-11-08 17:01:47', 0),
(6, 2, xxx, '2020-11-08 17:05:47', 0),
(7, 2, xxx, '2020-11-09 14:00:47', 0),
(8, 2, xxx, '2020-11-09 14:05:47', 0),
A typical approach is to filter with a correlated subquery:
select t.*
from mytable t
where t.draft = 0 and t.date = (
select min(t1.date)
from mytable t1
where t1.draft = t.draft and t1.user_id = t.user_id and date(t1.date) = date(t.date)
)
You can optimize the subquery a little by using a half-open interval for filtering:
select t.*
from mytable t
where t.draft = 0 and t.date = (
select min(t1.date)
from mytable t1
where
t1.user_id = t.user_id
and t1.draft = t.draft
and t1.date >= date(t.date)
and t1.date < date(t.date) + interval 1 day
)
The second query should be able to take advantage of an index on (draft, user_id, date).
Alternatively, if you are running MuSQL 8.0, you can also use window functions:
select *
from (
select t.*, row_number() over(partition by user_id, date(date) order by date) rn
from mytable t
where draft = 0
) t
where rn = 1
Use:
SELECT user_id, coords, date
FROM `table`
WHERE draft = 0
GROUP BY DAY('date'), user_id order by user_id, date
I'm trying to retrieve all columns data along with the time difference between all consecutive rows from the following table, where (sender_id = 1 OR = 2) and (recipient_id = 2 OR = 1).
CREATE TABLE records (
id INT(11) AUTO_INCREMENT,
send_date DATETIME NOT NULL,
content TEXT NOT NULL,
sender_id INT(11) NOT NULL,
recipient_id INT(11) NOT NULL,
PRIMARY KEY (id)
);
INSERT INTO records (send_date, content, sender_id, recipient_id) VALUES
('2013-08-23 14:50:00', 'record 1/5', 1, 2),
('2013-08-23 14:51:00', 'record 2/5', 2, 1),
('2013-08-23 15:50:00', 'record 3/5', 2, 1),
('2013-08-23 15:50:13', 'record 4/5', 1, 2),
('2013-08-23 16:50:00', 'record 5/5', 1, 2);
Problem is my select query won't output the latest record because of the WHERE clause :
SELECT t1.content, DATE_FORMAT(t1.send_date, '%b, %D, %H:%i') AS 'pprint_date',
TIMESTAMPDIFF(MINUTE, t1.send_date, t2.send_date) AS 'duration'
FROM records t1, records t2
WHERE (t1.id = t2.id - 1) /*<= this subtraction excludes latest record*/
AND ((t1.sender_id = 1 AND t1.recipient_id = 2)
OR (t1.sender_id = 2 AND t1.recipient_id = 1))
ORDER BY t1.id ASC
How can I properly get the time difference between all consecutive records while still printing all of them ?
I would use a correlated subquery:
select r.*,
(select r2.send_date
from records r2
where (r2.sender_id in (1, 2) or r2.recipient_id in (1, 2)) and
r2.send_date > r.send_date
order by r2.send_date asc
limit 1
) as next_send_date
from records r
where r.sender_id in (1, 2) or r.recipient_id in (1, 2);
You can get the duration (instead of the next time) by using TIMESTAMPDIFF(MINUTE, r.send_date, r2.send_date) in the subquery. I think the first version is easier for you to test with to see what is happening.
I have a table of users with basic details id, their names and profile photo (link to photo, actually)
CREATE TABLE IF NOT EXISTS `users` (
`id` int(11) NOT NULL,
`userName` varchar(60) NOT NULL,
`photo` varchar(50) NULL,
`status` int(11) NOT NULL
) ENGINE=InnoDB AUTO_INCREMENT=42 DEFAULT CHARSET=latin1;
INSERT INTO `users` (`id`, `userName`,`photo`, `status`) VALUES
(1, 'John', 'john.png',1),
(2, 'Jane', 'jane.png',1),
(3, 'Ali', '',1),
(6, 'Bruce', 'bruce.png',1),
(7, 'Martha', '',1),
(8, 'Sidney', '',1),
(10, 'Charlie', 'charlie.png',1),
(12, 'Elisa', '',1),
(14, 'Samantha', 'samantha.png',1),
(15, 'Hannah', 'hannah.png',1),
(16, 'Hannah', '',1),
(17, 'Kevin', 'kevin1.png',1),
(18, 'Kevin', 'kevin2.png',1),
(19, 'Ruth', '',1);
Not all users have profile picture. I would like to list these users in alphabetic order and also show users who have profile picture in front.
This is the query that I wrote:
select * from users ORDER BY photo DESC ;
It sorts users based on photo value but they are not being shown in alphabetic order.
Is it possible to list these users such that all users who have photos will appear top on the list with [userName] in alphabetic order?
SQL FIDDLE
Once you've changed '' to NULL...
SELECT * FROM users ORDER BY photo IS NULL,username;
You have empty vlaues here. So you can use this way.
SELECT * FROM users ORDER BY if(photo = '' or photo is null,1,0), userName
But in mysql has a method to order null values with (-).
SELECT * FROM users ORDER BY -photo DESC, userName ASC
Here photo column data order as null values last because of DESC order
OR
SELECT * FROM users ORDER BY
CASE WHEN photo IS NULL THEN 1 ELSE 0 END ASC, userName ASC
If you want 1st people without picture and then other (while sorting these 2 groups alphabetically):
select * from users ORDER BY photo,userName ASC ;
Waiting your feed back if it is not exactly what you want.
I have a table and having the following data
CREATE TABLE IF NOT EXISTS `tbl_ticket` (
`id` int(9) NOT NULL AUTO_INCREMENT,
`parent_id` int(11) NOT NULL,
`ticket_title` varchar(250) NOT NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 AUTO_INCREMENT=16 ;
--
-- Dumping data for table `tbl_ticket`
--
INSERT INTO `tbl_ticket` (`id`, `parent_id`, `ticket_title`) VALUES
(1, 0, 'tyty'),
(2, 0, 'testing'),
(3, 0, 'test from ticket'),
(4, 0, 'test ticket'),
(5, 0, 'test ticket'),
(6, 0, 'test ticket'),
(7, 0, 'test ticket'),
(8, 5, 'test ticket'),
(9, 0, '1 Ticket'),
(10, 0, '2Ticket'),
(11, 2, 'ticket2'),
(12, 2, 'ticket1'),
(13, 0, 'title 1234'),
(14, 0, 'titles 1234'),
(15, 14, 'sample 1234');
I need to return all rows where id is not present in parent id from the table.
Also if id is present in the parent_id column, I want to get the row having the highest id which matches the parent_id.
i.e. I need to return rows with id 1, 3,4,6,7,8,9,10, 12,13, 15.
I tried this sql
SELECT `id` , `parent_id`
FROM `tbl_ticket`
WHERE id NOT
IN (
SELECT parent_id
FROM tbl_ticket
)
but it returns value 11 also, instead it should return 12 which is the row having highest id with parent_id =2
Assuming the 5 in your expected output is a typo, as 5 appears in the parent_id field for id=8, you can get your result by the union of two simple queries.
select t1.id
from tbl_ticket t1
where not exists (
select 1 from tbl_ticket
where parent_id = t1.id
)
and parent_id = 0
union all
select max(id)
from tbl_ticket
where parent_id <> 0
group by parent_id
order by id asc
Fiddle here
The query is in two parts. the first part gets all the tickets that are not present in another tickets parent_id field, and which themselves do not have a parent (parent_id = 0).
The second part of the query looks at those tickets that DO have a parent (parent_id <> 0), and for each group of tickets that share the same parent_id, selects the one with the max id.
The results are then combined with a union to give a single result set. Since the two result sets are mutually exclusive, we can use union all to skip over the duplicate check.
If I understand correctly, you can do this with not exists rather than combining two separate queries. The advantage is that no duplicate elimination is needed (as is needed when you use union):
select t.*
from tbl_ticket t
where not exists (select 1
from tbl_ticket t2
where t2.parent_id = t.id
) or
not exists (select 1
from tbl_ticket t2
where t2.parent_id = t.id and t2.id > t.id
);
The first gets all rows that have no parents. The second gets all rows with the maximum id for a parent.
For best performance, you want an index on tbl_ticket(parent_id, id).
i am looking how to have unique value per day, here an exemple:
CREATE TABLE IF NOT EXISTS calls (
id int(11) default NULL,
calldate datetime default NULL,
dst varchar(80) NOT NULL
) ENGINE=MyISAM DEFAULT CHARSET=latin1;
INSERT INTO calls (id, calldate, dst) VALUES
(1, '2014-05-03 20:45:43', '22561037352'),
(2, '2014-05-04 20:07:49', '22561037352'),
(3, '2014-05-04 13:16:14', '22561037352'),
(4, '2014-05-04 20:08:58', '22560991034'),
(5, '2014-05-04 16:06:02', '22560991034'),
(6, '2014-05-04 20:22:19', '22560842218');
sqlfiddle: Copy and paste to test
we have two number coming two times per day 22561037352 & 22560991034, i want to show unique number per day.
http://sqlfiddle.com/#!9/84076/11
SELECT DISTINCT DATE_FORMAT (calldate,'%Y-%m-%d') calldate, dst
FROM calls
SELECT DISTINCT t.*
FROM (SELECT DATE (calldate) as calldate, dst FROM calls) t
First call to the number for the day
SELECT *
FROM calls c
WHERE NOT EXISTS (SELECT 'a'
FROM calls c2
WHERE c2.dst = c.dst
AND DATE_FORMAT(c2.calldate,'%d/%m/%Y') = DATE_FORMAT(c.calldate,'%d/%m/%Y')
AND c2.calldate < c.calldate
)