Query to get latest training date - mysql

We have 2 tables one is driver with all the driver details and the table is dTraining.
Structure for driver is
CREATE TABLE IF NOT EXISTS `driver` (
`driverID` int(5) NOT NULL,
`clientID` int(5) NOT NULL,
`driverName` varchar(100) NOT NULL,
`driverDateOfBirth` date NOT NULL,
`driverStatus` enum('a','d','i') NOT NULL DEFAULT 'a'
) ENGINE=InnoDB DEFAULT CHARSET=latin1;
Structure for dTraining is
CREATE TABLE IF NOT EXISTS `dTraining` (
`dTrainingID` int(5) NOT NULL,
`cTrainingID` int(5) NOT NULL,
`trainingID` int(11) NOT NULL,
`driverID` int(5) NOT NULL,
`clientID` int(5) NOT NULL,
`driverTrainingDate` date NOT NULL,
`driverTrainingUpdateStatus` enum('d','a') NOT NULL
) ENGINE=InnoDB DEFAULT CHARSET=latin1;
What I need is that when I run a query like this should give be the latest training from the many training data which the driver has. So I need help on how to run the subquery there.
SELECT driver.driverID,dTraining.driverTrainingDate
FROM driver,dTraining
Currently I have this query . Sample output will be
driverID=1 , driverTrainingDate=2013-02-01
driverID=2 , driverTrainingDate=2013-02-02
SELECT driver.driverID,b.driverTrainingDate
FROM driver
LEFT JOIN (
SELECT B1.*
FROM dTraining AS B1
LEFT JOIN dTraining AS B2
ON B1.driverID = B2.driverID
AND B1.cTrainingID = B2.cTrainingID
AND B1.driverTrainingDate< B2.driverTrainingDate
WHERE B1.cTrainingID =".$cTID." And B2.driverID IS NULL) as b
ON ( driver.driverID= b.driverID)
What I am curious why do we need to put B1.driverTrainingDate< B2.driverTrainingDate and not B1.driverTrainingDate> B2.driverTrainingDate and the need for B2.driverID IS NULL

The left join with B2 returns trainings that happened after these of B1, that's why if none exist (B2.driverID is null) you're sure B1's training is the last one.

try this, change '123' for the driverID:
select d.*,t.*
from driver as d
inner join dtraining as t
on d.driverId=t.driverId
where d.driverid in (1,2,3,4.......10000)
order by t.driverTrainingDate desc
limit 1

Related

list all left for all dates and ids nulls SQL

Hi i have a problem with a query i want to do
the tables are:
CREATE TABLE `lista` (
`job` varchar(20) NOT NULL,
`tipo` varchar(20) NOT NULL,
`nombre` varchar(256) NOT NULL,
PRIMARY KEY (`job`)
);
CREATE TABLE `updatesjobs` (
`job` varchar(20) NOT NULL,
`odate` varchar(8) NOT NULL,
`status` varchar(5) NOT NULL,
`runtime` varchar(20) NOT NULL,
`endtime` varchar(20) NOT NULL
);
the table updatesjobs doesnt have jobs for all odates
if i do this
select l.nombre,l.job,u.odate
from lista l
left
join updatesjobs u
on l.job=u.job
and u.odate = "20200615"
it appears the information
01. text01 JOB1 20200615
02. text02 JOB2 NULL
03. text03 JOB3 20200615
04. text04 JOB4 NULL
05. text05 JOB5 20200615
06. text06 JOB6 NULL
the information appear as it should be but i dont want to filter by date
i need to appear for all dates the dates dont have a job executed
If I correctly understood your question, you can enumerate all available dates in updatejobs, cross join the results with jobs from table lista, and finally use not exists to identify the missing rows in updatejobs:
select l.nombre, l.job, d.odate
from lista l
cross join (select distinct o.date from updatejobs) d
where not exists (
select 1 from updatesjobs u where u.job = l.job and u.odate = d.odate
)

I get combined rows when i use join query

I use the following query:
select *
from TEST2 t1 join TEST2 t2
where t1.TID <> t2.TID
and t1.ST = t2.ST
and t1.SAL > t2.SAL
and t1.TR < t2.TR;
I have 16 attributes in my table. But when i fire the above query i get result of two rows combined in one row with 32 attributes.
I want to get the result as two different rows and not one row, i.e the combination of both in one row.
6|Mark|Murro|M|970|-3134|Denver|CO|80251|S|Y|70000|4|0|0|0|0
2|Chunho|Black|M|719|-4662|Denver|CO|80290|M|N|60000|5|0|0|0
As shown above, both the rows get combined and comes as
6|Mark|Murro|M|970|-3134|Denver|CO|80251|S|Y|70000|4|0|0|0|0|2|Chunho|Black|M|719|-4662|Denver|CO|80290|M|N|60000|5|0|0|0
Table Schema :
CREATE TABLE `TEST2` (
`TID` int(11) DEFAULT NULL,
`FN` text,
`LN` text,
`GD` text,
`AC` int(11) DEFAULT NULL,
`PH` text,
`CT` text,
`ST` text,
`ZIP` int(11) DEFAULT NULL,
`MS` text,
`CH` text,
`SAL` int(11) DEFAULT NULL,
`TR` int(11) DEFAULT NULL,
`STX` int(11) DEFAULT NULL,
`MTX` int(11) DEFAULT NULL,
`CTX` int(11) DEFAULT NULL
) ENGINE=InnoDB DEFAULT CHARSET=latin1;
But i want them seperate
Please help me out
It is a little unclear what you are really trying to do, but the following should implement your logic
select t.*
from test2 t
where exists (select 1
from test2 t2
where t.tid <> t2.tid and t.st = t2.st and t.sal > t2.sal and t.tr < t2.tr
) or
exists (select 1
from test2 t2
where t.tid <> t2.tid and t.st = t2.st and t.sal < t2.sal and t.tr > t2.tr
);
Because you want both rows, it needs to check for the conditions in both directions.

How to INNER JOIN around a loop of tables

I have four tables as follows:
CREATE TABLE IF NOT EXISTS `categories` (
`id` int(10) unsigned NOT NULL AUTO_INCREMENT,
`name` varchar(255) NOT NULL,
PRIMARY KEY (`id`),
) ENGINE=MyISAM DEFAULT CHARSET=utf8 ;
CREATE TABLE IF NOT EXISTS `categories_friends` (
`category_id` int(10) unsigned NOT NULL,
`friend_id` int(10) unsigned NOT NULL,
UNIQUE KEY `category_id` (`friend_id`,`category_id`)
) ENGINE=MyISAM DEFAULT CHARSET=utf8;
CREATE TABLE IF NOT EXISTS `friends` (
`id` int(10) unsigned NOT NULL AUTO_INCREMENT,
`user_id` int(10) unsigned NOT NULL,
`friend_id` int(10) unsigned NOT NULL,
PRIMARY KEY (`id`),
UNIQUE KEY `user_id` (`user_id`,`friend_id`)
) ENGINE=MyISAM DEFAULT CHARSET=utf8 ;
CREATE TABLE IF NOT EXISTS `ratings` (
`id` int(10) unsigned NOT NULL AUTO_INCREMENT,
`user_id` int(10) unsigned NOT NULL,
`category_id` int(10) unsigned NOT NULL,
`title` varchar(255) NOT NULL,
`description` text NOT NULL,
`rating` tinyint(2) unsigned NOT NULL,
`public` tinyint(1) NOT NULL DEFAULT '0',
`created` datetime NOT NULL,
PRIMARY KEY (`id`),
) ENGINE=MyISAM DEFAULT CHARSET=utf8 ;
I am trying to perform the following query on those tables:
SELECT *
FROM `favred`.`ratings` AS `Rating`
INNER JOIN `favred`.`friends` AS `JFriend`
ON (`JFriend`.`friend_id` = `Rating`.`user_id`)
INNER JOIN `favred`.`categories_friends` AS `JCategoriesFriend`
ON (`JCategoriesFriend`.`category_id` = `Rating`.`category_id`
AND `JCategoriesFriend`.`friend_id` = `JFriend`.`id`)
INNER JOIN `favred`.`categories` AS `JCategory`
ON (`JCategory`.`id` = `Rating`.`category_id`
AND `JCategory`.`id` = `JCategoriesFriend`.`category_id`)
WHERE `JFriend`.`user_id` = 1
AND `Rating`.`user_id` <> 1
AND `JCategory`.`id` IN (4, 14)
GROUP BY `Rating`.`id`
The query above is not working, as it returns no results (although there is data in the tables that should return), what I'm trying to do is to find all the Ratings that were not authored by me (ID:1), but were authored by my Friends, but only if I've selected to view a specific Category for that Friend, with the resulting set being filtered by a given set of specific Categories.
The INNER JOINs loop around through Rating --> Friend --> CategoriesFreind --> Category --> back to Rating.
If I remove the additional portion of the INNER JOIN's ON clauses as follows:
SELECT *
FROM `favred`.`ratings` AS `Rating`
INNER JOIN `favred`.`friends` AS `JFriend`
ON (`JFriend`.`friend_id` = `Rating`.`user_id`)
INNER JOIN `favred`.`categories_friends` AS `JCategoriesFriend`
ON (`JCategoriesFriend`.`friend_id` = `JFriend`.`id`)
INNER JOIN `favred`.`categories` AS `JCategory`
ON (`JCategory`.`id` = `JCategoriesFriend`.`category_id`)
WHERE `JFriend`.`user_id` = 1
AND `Rating`.`user_id` <> 1
AND `JCategory`.`id` IN (4, 14)
GROUP BY `Rating`.`id`
then the query will return results, but because the INNER JOIN joining the CategoriesFriend to the Rating is not being filtered by the 'JCategory'.'id' IN (4, 14) clause, it returns all Ratings by that friend instead of filtered as it should be.
Any suggestions on how to modify my query to get it to pull the filtered results?
And I'm using CakePHP, so a query that would fit into it's unique query format would be preferred although not required.
first ,why are you use the JFriend.id, does it mean something,or is it as the same as user_id?
try this one,the same logic but it's from top to bottom ,I feel:
SELECT * FROM categories as JCategory
INNER JOIN categories_friends as JCategoriesFriend ON JCategoriesFriend.category_id = JCategory.id
INNER JOIN friends AS JFriend ON JFriend.friend_id = JCategoriesFriend.friend_id
INNER JOIN ratings AS Rating ON Rating.user_id = JFriend.friend_id
WHERE JCategory.id IN (4,14) AND JFriend.user_id = 1 AND Rating.user_id <> 1 GROUP BY Rating.id
I got one result from all the data that I made for the testing.
if it does not work also,try make some correct data,maybe the data is not right...
the testing data below:
categories: id | name (14| 141414)
categories_friends: category_id| friend_id (14| 2)
friends: id | user_id | friend_id (4| 1| 2)
ratings: id | user_id | category_id | title (2| 2| 14 | 'haha')
So I wondered if the INNER JOINs were being a little too limiting and specific in their ON clauses. So I thought that maybe a LEFT JOIN would work better...
SELECT *
FROM `favred`.`ratings` AS `Rating`
INNER JOIN `favred`.`friends` AS `JFriend`
ON (`JFriend`.`friend_id` = `Rating`.`user_id`)
LEFT JOIN `favred`.`categories_friends` AS `JCategoriesFriend`
ON (`JCategoriesFriend`.`friend_id` = `JFriend`.`id`
AND `JCategoriesFriend`.`category_id` = `Rating`.`category_id`)
WHERE `JFriend`.`user_id` = 1
AND `JRatingsUser`.`id` IS NULL
AND `Rating`.`user_id` <> 1
GROUP BY `Rating`.`id`
That query worked for me.
I did away with linking to the categories table directly, and linked indirectly through the categories_friends table which sped up the query a little bit, and everything is working great.

Some help needed with a SQL query

I need some help with a MySQL query. I have two tables, one with offers and one with statuses. An offer can has one or more statuses. What I would like to do is get all the offers and their latest status. For each status there's a table field named 'added' which can be used for sorting.
I know this can be easily done with two queries, but I need to make it with only one because I also have to apply some filters later in the project.
Here's my setup:
CREATE TABLE `test`.`offers` (
`id` INT UNSIGNED NOT NULL AUTO_INCREMENT PRIMARY KEY ,
`client` TEXT NOT NULL ,
`products` TEXT NOT NULL ,
`contact` TEXT NOT NULL
) ENGINE = MYISAM ;
CREATE TABLE `statuses` (
`id` int(10) unsigned NOT NULL AUTO_INCREMENT,
`offer_id` int(11) NOT NULL,
`options` text NOT NULL,
`deadline` date NOT NULL,
`added` datetime NOT NULL,
PRIMARY KEY (`id`)
) ENGINE=MyISAM DEFAULT CHARSET=latin1
Should work but not very optimal imho :
SELECT *
FROM offers
INNER JOIN statuses ON (statuses.offer_id = offers.id
AND statuses.id =
(SELECT allStatuses.id
FROM statuses allStatuses
WHERE allStatuses.offer_id = offers.id
ORDER BY allStatuses.added DESC LIMIT 1))
Try this:
SELECT
o.*
FROM offers o
INNER JOIN statuses s ON o.id = s.offer_id
ORDER BY s.added
LIMIT 1

MySQL query killing my server

Looking at this query there's got to be something bogging it down that I'm not noticing. I ran it for 7 minutes and it only updated 2 rows.
//set product count for makes
$tru->query->run(array(
'name' => 'get-make-list',
'sql' => 'SELECT id, name FROM vehicle_make',
'connection' => 'core'
));
while($tempMake = $tru->query->getArray('get-make-list')) {
$tru->query->run(array(
'name' => 'update-product-count',
'sql' => 'UPDATE vehicle_make SET product_count = (
SELECT COUNT(product_id) FROM taxonomy_master WHERE v_id IN (
SELECT id FROM vehicle_catalog WHERE make_id = '.$tempMake['id'].'
)
) WHERE id = '.$tempMake['id'],
'connection' => 'core'
));
}
I'm sure this query can be optimized to perform better, but I can't think of how to do it.
vehicle_make = 45 rows
taxonomy_master = 11,223 rows
vehicle_catalog = 5,108 rows
All tables have appropriate indexes
UPDATE: I should note that this is a 1-time script so overhead isn't a big deal as long as it runs.
CREATE TABLE IF NOT EXISTS `vehicle_make` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`name` varchar(32) NOT NULL,
`product_count` int(11) NOT NULL,
PRIMARY KEY (`id`)
) ENGINE=MyISAM DEFAULT CHARSET=latin1 AUTO_INCREMENT=46 ;
CREATE TABLE IF NOT EXISTS `taxonomy_master` (
`product_id` int(10) NOT NULL,
`v_id` int(10) NOT NULL,
`vehicle_requirement` varchar(255) DEFAULT NULL,
`is_sellable` enum('True','False') DEFAULT 'True',
`programming_override` varchar(25) DEFAULT NULL,
PRIMARY KEY (`product_id`,`v_id`),
KEY `idx2` (`product_id`),
KEY `idx3` (`v_id`)
) ENGINE=MyISAM DEFAULT CHARSET=latin1;
CREATE TABLE IF NOT EXISTS `vehicle_catalog` (
`v_id` int(10) NOT NULL,
`id` int(11) NOT NULL,
`v_make` varchar(255) NOT NULL,
`make_id` int(11) NOT NULL,
`v_model` varchar(255) NOT NULL,
`model_id` int(11) NOT NULL,
`v_year` varchar(255) NOT NULL,
PRIMARY KEY (`v_id`,`v_make`,`v_model`,`v_year`),
UNIQUE KEY `idx` (`v_make`,`v_model`,`v_year`),
UNIQUE KEY `idx2` (`v_id`)
) ENGINE=MyISAM DEFAULT CHARSET=latin1;
Update: The successful query to get what I needed is here....
SELECT
m.id,COUNT(t.product_id) AS CountOf
FROM taxonomy_master t
INNER JOIN vehicle_catalog v ON t.v_id=v.id
INNER JOIN vehicle_make m ON v.make_id=m.id
GROUP BY m.id;
without the tables/columns this is my best guess from reverse engineering the given queries:
UPDATE m
SET product_count =COUNT(t.product_id)
FROM taxonomy_master t
INNER JOIN vehicle_catalog v ON t.v_id=v.id
INNER JOIN vehicle_make m ON v.make_id=m.id
GROUP BY m.name
The given code loops over each make, and then runs a query the counts for each. My answer just does them all in one query and should be a lot faster.
have an index for each of these:
vehicle_make.id cover on name
vehicle_catalog.id cover make_id
taxonomy_master.v_id
EDIT
give this a try:
CREATE TEMPORARY TABLE CountsOf (
id int(11) NOT NULL
, CountOf int(11) NOT NULL DEFAULT 0.00
);
INSERT INTO CountsOf
(id, CountOf )
SELECT
m.id,COUNT(t.product_id) AS CountOf
FROM taxonomy_master t
INNER JOIN vehicle_catalog v ON t.v_id=v.id
INNER JOIN vehicle_make m ON v.make_id=m.id
GROUP BY m.id;
UPDATE taxonomy_master,CountsOf
SET taxonomy_master.product_count=CountsOf.CountOf
WHERE taxonomy_master.id=CountsOf.id;
instead of using nested query ,
you can separated this query to 2 or 3 queries,
and in php insert the result of the inner query to the out query ,
its faster !
#haim-evgi Separating the queries will not increase the speed significantly, it will just shift the load from the DB server to the Web server and create overhead of moving data between the two servers.
I am not sure with the appropriate indexes you run such query 7 minutes. Could you please show the table structure of the tables involved in these queries.
Seems like you need the following indices:
INDEX BTREE('make_id') on vehicle_catalog
INDEX BTREE('v_id') on taxonomy_master