query with INNER JOIN - java

The tables are created and have some data inserted I am trying to get the route from the arrivaltimes table with the aid of JOIN INNER but I am getting nothing back I have already tried to adjust the time to the current time tin th arrivaltimes table but the result is always empty. I am not getting any error. Is something wrong with my query?
CREATE TABLE IF NOT EXISTS stops
(stop_id INT(11) NOT NULL AUTO_INCREMENT PRIMARY KEY,
name varchar(30) NOT NULL,
lat double(10,6) NOT NULL,
longi double(10,6)NOT NULL)
CREATE TABLE IF NOT EXISTS arrivaltimes
(arrivaltimes_id INT(11) NOT NULL AUTO_INCREMENT PRIMARY KEY,
weekday VARCHAR(20) NOT NULL,
route INT(11) NOT NULL,
arrivaltime time NOT NULL,
stop_id INT, FOREIGN KEY fk_stop_id(stop_id) REFERENCES stops(stop_id) )
SELECT route from arrivaltimes INNER JOIN stops ON arrivaltimes.stop_id=stops.stop_id where arrivaltime = now()

arrivaltime is having datatype time and its in the format H:i:s.
In the where clause you are using now() and it will be in the format Y-m-d H:i:s
You need to use curtime function for that.
mysql> select now();
+---------------------+
| now() |
+---------------------+
| 2015-05-10 23:46:44 |
+---------------------+
1 row in set (0.00 sec)
mysql> select curtime();
+-----------+
| curtime() |
+-----------+
| 23:46:53 |
+-----------+
1 row in set (0.00 sec)
where arrivaltime = curtime()

your query is perfectly fine the problem is only with the time you provide as input.
The format of TIME data type is 'HH:MM:SS' so use time(now()) this will give you proper results.
mysql> select time(now());

Related

Trigger is not updating current record PostgresSQL when record is inserted from hibernate

I have one table which stores interview slots with start and end times below is the table:
CREATE TABLE INTERVIEW_SLOT (
ID SERIAL PRIMARY KEY NOT NULL,
INTERVIEWER INTEGER REFERENCES USERS(ID) NOT NULL,
START_TIME TIMESTAMP NOT NULL, -- start time of interview
END_TIME TIMESTAMP NOT NULL, -- end time of interview
-- more columns are not necessary for this question
);
I have created a trigger which will truncate start and end time to minutes below is the trigger:
CREATE OR REPLACE FUNCTION
iv_slot_ai() returns trigger AS
$BODY$
BEGIN
raise warning 'cleaning start and end time for iv slot for id: %', new.id;
update interview_slot set end_time = TO_TIMESTAMP(end_time::text, 'YYYY-MM-DD HH24:MI');
update interview_slot set start_time = TO_TIMESTAMP(start_time::text, 'YYYY-MM-DD HH24:MI');
return new;
END;
$BODY$
LANGUAGE plpgsql VOLATILE;
CREATE TRIGGER IV_SLOT_AI AFTER INSERT ON INTERVIEW_SLOT
FOR EACH ROW
EXECUTE PROCEDURE iv_slot_ai();
When I insert a record from psql terminal manually trigger gets hit and updates the inserted record properly.
INSERT INTO public.interview_slot(
interviewer, start_time, end_time, is_booked, created_on, inform_email_timestamp)
VALUES (388, '2022-08-22 13:00:10.589', '2022-08-22 13:30:09.589', 'F', current_date, current_date);
WARNING: cleaning start and end time for iv slot for id: 72
INSERT 0 1
select * from interview_slot order by id desc limit 1;
id | interviewer | start_time | end_time |
----+-------------+-------------------------+-------------------------+
72 | 388 | 2022-08-22 13:00:00 | 2022-08-22 13:30:00 |
I have a backend application in spring boot with hibernate ORM. When I insert the record from API call, it gets triggered(i have checked in Postgres logs) but the inserted record does not get updated.
Actually, method which saves records is being called from another method that has this #Transactional() annotation.
I have also tried BEFORE trigger but it was also not working.
Can anyone explain why this is happening and what is the solution?
Is it because of transactional annotation?
The OMR might be updating. Use BEFORE INSERT OR UPDATE trigger with this somewhat simpler function (w/o the message) using date_trunc:
create or replace function iv_slot_ai() returns trigger language plpgsql as
$body$
begin
new.start_time := date_trunc('minute', new.start_time);
new.end_time := date_trunc('minute', new.end_time);
return new;
end;
$body$;

Unique constraints & insert or update for both MySQL and SQLite

I am looking for a way to define a set of columns as unique and then insert a new entry into the table or update the row if the columns aren't unique. I have done some research and found ways to do it, but I couldn't find anything that is compatible with both MySQL and SQLite.
Say I have the following table:
CREATE TABLE `users` (
`id` INT NOT NULL AUTO_INCREMENT,
`uuid` VARCHAR ( 64 ) NOT NULL,
`name` VARCHAR ( 32 ) NOT NULL,
`date` BIGINT NULL,
PRIMARY KEY ( id )
);
I want uuid and date to be unique so that there can be multiple entries for one uuid or one date, but not for one combination of uuid and date. What I initially wanted to do is set the primary key to those:
PRIMARY KEY ( uuid, date )
However, for some reason I won't be able to use null values for date when doing this.
I have also found something about a constraint, but I am not sure if this works:
CONSTRAINT user UNIQUE ( `uuid`, `date` )
Now I want to insert a new row into this table, but update the existing row if a row with the same uuid and date already exists. I have found a few ways but they are either not doing what I want or not compatible with both MySQL and SQLite:
INSERT INTO ... ON DUPLICATE KEY doesn't work with SQLite
REPLACE INTO will delete anything I don't specify instead of updating
I have been doing research for quite a while but I couldn't find a solution that worked for me. Any help appreciated.
SQLite solution (same principle should apply in mysql)
You could simply add a UNIQUE index (at least for SQLite for which this is for) so you could have :-
DROP TABLE IF EXISTS `users`;
CREATE TABLE IF NOT EXISTS `users` (
`id` INTEGER, //<<<<<<<<<< See notes below
`uuid` VARCHAR ( 64 ) NOT NULL,
`name` VARCHAR ( 32 ) NOT NULL,
`date` BIGINT NULL,
PRIMARY KEY ( `id` )
);
CREATE UNIQUE INDEX IF NOT EXISTS uuid_date ON `users` (`uuid`,`date`); //<<<<<<<<<<
Note AUTO_INCREMENT results in a failure for SQLite as it's not a keyword, the correct keyword in SQlite is AUTOINCREMENT. However, it's been omitted as it's probably not required as INTEGER PRIMARY KEY (or the implicit by specifiying PRIMARY KEY (id)) will result in a uniqiue id being automatically generated if no value is supplied for the column when inserting.
SQLite requires INTEGER, not INT, for the automatically generated id. NOT NULL and also UNIQUE are implied so no need to specify them.
Here's two sets of example inserts each duplicating the uuid/date combination thus updating instead of inserting and also inserting with same uuid but different date and vice-versa :-
INSERT OR REPLACE INTO `users` VALUES(null,'Fred01234567','Fred Bloggs the 1st','20180101');
INSERT OR REPLACE INTO `users` VALUES(null,'Fred01234567','Fred Bloggs the 2nd','20180101'); -- <<<< DUPLICATE
INSERT OR REPLACE INTO `users` VALUES(null,'Fred99999999','Fred Bloggs the 2nd','20180101'); -- <<<< different uuid same date
INSERT OR REPLACE INTO `users` VALUES(null,'Fred01234567','Fred Bloggs the 2nd','99999999'); -- <<<< same uuid different date
INSERT OR REPLACE INTO `users` (`uuid`,'name','date') VALUES('Fred76543210','Fred NotBloggs the 1st','20180202');
INSERT OR REPLACE INTO `users` (`uuid`,'name','date') VALUES('Fred76543210','Fred NotBloggs the 1st','20180202');
INSERT OR REPLACE INTO `users` (`uuid`,'name','date') VALUES('Fred99999999','Fred NotBloggs the 1st','20180202');
INSERT OR REPLACE INTO `users` (`uuid`,'name','date') VALUES('Fred76543210','Fred NotBloggs the 1st','99999999');
SELECT * FROM `users`;
Results are :-
I have been googling for a few hours and did some testing with both MySQL and SQLite and I think I found a working solution.
To make the combination of uuid and date unique, I have added a unique constraint to the table. To insert a new row or 'update' an existing row, I am using REPLACE INTO ... SELECT.
To create the table:
CREATE TABLE IF NOT EXISTS `users` (
`id` INT NOT NULL AUTO_INCREMENT, // use INTEGER NOT NULL for SQLite
`uuid` VARCHAR ( 64 ) NOT NULL,
`name` VARCHAR ( 32 ) NOT NULL,
`date` BIGINT NULL,
CONSTRAINT `uuid_date` UNIQUE ( `uuid`, `date` ),
PRIMARY KEY ( `id` )
);
The CONSTRAINT will make sure the combination of uuid and date is always unique.
For inserting data, I use REPLACE INTO ... SELECT, where I enter all (new) values in the SELECT query and enter the column names for all columns I haven't specified a value for, to ensure it will keep their values intact rather than deleting them when the existing row is replaced.
REPLACE INTO `users`
SELECT `id`, `uuid`, ?, `date`
FROM `users` WHERE `uuid` = ? AND `date` = ?;
Of course, because in this case there are no columns that can be lost when using a normal REPLACE INTO, so I could also use:
REPLACE INTO `users` ( `uuid`, `name`, `date` ) VALUES ( ?, ?, ? );
However, the REPLACE INTO ... SELECT query can be useful when I have a table with more columns and there are actually columns that can be lost when not selecting them.
Sorry about all the comments. Here is how I achieved what I think you are going for. You are going to lose the id as Primary Key on your users table. You will also have to stage your insert variables in a table. But you will get your end results. Sorry I do not have a better solution.
DROP TABLE users;
DROP TABLE users2;
CREATE TABLE `users` (
`uuid` VARCHAR ( 64 ) NOT NULL,
`name` VARCHAR ( 32 ) NOT NULL,
`date` BIGINT NULL
);
ALTER TABLE `users` ADD PRIMARY KEY(`uuid`,`date`);
INSERT INTO users (`name`,`uuid`,`date`) SELECT '','123','2018-04-01';
CREATE TABLE `users2` (
`uuid` VARCHAR ( 64 ) NOT NULL,
`name` VARCHAR ( 32 ) NOT NULL,
`date` BIGINT NULL
);
INSERT INTO users2 (`name`,`uuid`,`date`) SELECT 'brad','123','2018-04-01';
REPLACE INTO users SELECT `uuid`,`name`,`date` FROM users2 GROUP BY `uuid`,`date`;
SELECT * FROM users;`

Generic Format DateTime for MySQL and Oracle

I want to cast a string to UTC date. But with environments, database varies and code needs to be changed accordingly as below.
if env1
//mysql
insert into table values (STR_TO_DATE('datetime','%%m/%%d/%%Y %%H:%%i:%%s'))
else
//oracle
insert into table values (to_date('%s', 'MM/DD/YYYY HH24:MI:SS'))
So, Is there a way to handle this generic? by just generating UTC date in code itself and then inserting in database accordingly with any date exception in database?
PreparedStatement has three methods to use to set dates: setDate, setTime and setTimestamp.
You can use either of them that suits you best.
To get the PreparedStatement object, call .prepareStatement("your sql query") on your connection ojbect.
In your case, your query will be "insert into table values (?)"
Within the databases, you can use the same INSERT statement if you use a TIMESTAMP literal (MySQL documentation, Oracle documentation):
SQL Fiddle
Oracle 11g R2 Schema Setup:
CREATE TABLE table_name ( value DATE );
INSERT INTO table_name ( value ) VALUES ( TIMESTAMP '2018-03-23 11:12:00' );
Query 1:
SELECT * FROM table_name
Results:
| VALUE |
|----------------------|
| 2018-03-23T11:12:00Z |
SQL Fiddle
MySQL 5.6 Schema Setup:
CREATE TABLE table_name ( value TIMESTAMP );
INSERT INTO table_name ( value ) VALUES ( TIMESTAMP '2018-03-23 11:12:00' );
Query 1:
SELECT * FROM table_name
Results:
| value |
|----------------------|
| 2018-03-23T11:12:00Z |

SQL - Get Count

I have a table called COMPANIES that contains info on different companies. How do make a query that gets the company state(COMPANY_STATE) and the company name(COMPANY) count of the most used state (COMPANY_STATE) which has the highest number of different COMPANIES in it. So say Ohio has the most companies in it with 50. How to I query the database to get the state
| COMPANY_STATE | COUNT |
+---------------+-------+
| OH | 50 |
+---------------+-------+
Can i do this via query or do i have to have my java program actually do the work?
Table.sql
CREATE TABLE COMPANIES (
ID INT NOT NULL AUTO_INCREMENT,
COMPANY varchar(255) NOT NULL,
COMPANY_CODE char(10) NOT NULL,
COMPANY_ADDRESS varchar(255),
COMPANY_STATE char(2) NOT NULL,
COMPANY_WORKFORCE INT,
PRIMARY KEY (ID)
)
SELECT COMPANY_STATE, COUNT(ID) FROM COMPANIES
GROUP BY COMPANY_STATE
ORDER BY COUNT(ID) DESC
LIMIT 1

Get the value of the last inserted record

I am trying to get the stop_name of the last inserted row in the table with preparedStatement. How can I get the last inserted one?
I appreciate any help.
behavoiur table:
CREATE TABLE IF NOT EXISTS behaviour(
behaviour_id INT(11) NOT NULL AUTO_INCREMENT PRIMARY KEY,
mac VARCHAR(30) NOT NULL,
stop_name VARCHAR(30) NOT NULL,
stop_distance INT(11) NOT NULL,
speed INT(11) NOT NULL,
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
);
You may try this query:
select stop_name from behaviour where created_at in (select max(created_at) from behaviour)
Another solution:
select stop_name from behaviour order by behaviour_id desc limit 1;

Categories