I have tables for multiple stations with data from each station: timestamp, error etc. The total number of rows in each table is the frequency of errors at that station. The name of the station is in the table name.
CREATE TABLE Station_00 (error INT, timestamp DATETIME);
INSERT INTO Station_00 VALUES (1, '2020/10/05 12-12-12'),(2,'2020/10/05 12-12-15'),(3,'2020/10/05 12-12-20'),(4,'2020/10/05 12-12-25'),(5,'2020/10/05 12-12-30'),(6,'2020/10/05 12-12-35'),(7,'2020/10/05 12-12-37'),(8,'2020/10/05 12-12-40');
CREATE TABLE Station_01 (error INT, timestamp DATETIME);
INSERT INTO Station_01 VALUES (1, '2020/10/05 12-14-12'),(2,'2020/10/05 12-14-15'),(3,'2020/10/05 12-14-20'),(4,'2020/10/05 12-14-25');
CREATE TABLE Station_02 (error INT, timestamp DATETIME);
INSERT INTO Station_02 VALUES (1, '2020/10/05 12-14-17'),(2,'2020/10/05 12-14-20'),(3,'2020/10/05 12-14-26'),(4,'2020/10/05 12-14-29'),(5,'2020/10/07 12-14-29');
CREATE TABLE Station_03 (error INT, timestamp DATETIME);
INSERT INTO Station_03 VALUES (1, '2020/10/05 12-17-12'),(2,'2020/10/05 12-17-15'),(3,'2020/10/07 12-14-20'),(4,'2020/10/07 12-14-25'),(5,'2020/10/07 12-14-30'),(6,'2020/10/07 12-16-25');
Event values are random, not necessarily in ascending order like here.
I want to create a VIEW with as many rows as there are stations and columns station (the name of each table) and frequency (the number of rows in each table). Is there any way to do that in one SELECT ?
I would like something like:
+---------+-----------+
| Station | Frequency |
+---------+-----------+
| 00 | 8 |
| 01 | 4 |
| 02 | 5 |
| 03 | 6 |
+---------+-----------+
You could use union all:
create view myview as
select '00' as station, count(*) as cnt from table_station00
union all select '01', count(*) from table_station01
union all select '02', count(*) from table_station02
Note, however, that all these tables should probably be consolidated in a single table, with an additional column that represents the station. Then, you could just do:
select station, count(*) cnt from table_station;
Related
I have 3 table: Route, Bus_stop, Route-Bus_stop
Route: id, weekday, weekend
Bus_stop: id, name
Route-Bus_stop: primary key(order, time), foreign key: idRoute, idBus_stop
Insert into Route(id,weekday,weekend) values(1,1,1);
Insert into Route(id,weekday,weekend) values(2,1,1);
Insert into Bus_stop(id,name) values(1,'A');
Insert into Bus_stop(id,name) values(2,'B');
Insert into Bus_stop(id,name) values(3,'C');
Insert into Route-Bus_stop(idRoute,idBus_stop,routeo_rder,stoptime) values(1,1,0,7:00);
Insert into Route-Bus_stop(idRoute,idBus_stop,route_order,stoptime) values(1,2,1,7:10);
Insert into Route-Bus_stop(idRoute,idBus_stop,route_order,stoptime) values(1,3,2,7:30);
Insert into Route-Bus_stop(idRoute,idBus_stop,route_order,stoptime) values(2,3,0,15:00);
Insert into Route-Bus_stop(idRoute,idBus_stop,route_order,stoptime) values(2,2,1,15:10);
Insert into Route-Bus_stop(idRoute,idBus_stop,route_order,stoptime) values(2,1,2,15:20);
-- this is only an example, my database is bigger.
One of the route goes A -> B -> C, the other C->B->A
If the user wants to go A to C, how can I show only one of the routes with all of the bus stations to the destination?
I've write this query, but this shows both of the routes.
select *idRoute from Route-Bus_stop where idBus_stop=1 or idBus_stop=3 order by time; // A -> C
This will show route A->C and C-> A. But I want only the A->C
First don_'t rßuse reserved words like ORDER or TIME as column names, so you spre the need to use backticks all the tiome
Also Route-Bus_stop is also not valid without Backticks.
For your query you keed a selfjoin to get starting point and end point
CREATE TABLE Route_Bus_stop (
idRoute int
,idBus_stop int
,`order` int
,`time` varchar(10))
Insert into Route_Bus_stop(idRoute,idBus_stop,`order`,`time`) values(1,1,0,'7:00');
Insert into Route_Bus_stop(idRoute,idBus_stop,`order`,`time`) values(1,2,1,'7:10');
Insert into Route_Bus_stop(idRoute,idBus_stop,`order`,`time`) values(1,3,2,'7:30');
Insert into Route_Bus_stop(idRoute,idBus_stop,`order`,`time`) values(2,3,0,'15:00');
Insert into Route_Bus_stop(idRoute,idBus_stop,`order`,`time`) values(2,2,1,'15:10');
Insert into Route_Bus_stop(idRoute,idBus_stop,`order`,`time`) values(2,1,2,'15:20');
SELECT r1.idRoute,r1.idBus_stop,r2.idBus_stop,r1.`time`, r2.`time`
FROM Route_Bus_stop r1 INNER JOIN Route_Bus_stop r2
ON r1.idRoute = r2.idRoute AND r1.`order` < r2.`order`
WHERE r1.idBus_stop = 1
AND r2.idBus_stop = 3
idRoute | idBus_stop | idBus_stop | time | time
------: | ---------: | ---------: | :--- | :---
1 | 1 | 3 | 7:00 | 7:30
db<>fiddle here
I have search already an answer but i can't find one that is good for my situation.
I have a table called Names like this
ID NAME Age
1 Paula 20
2 Mark 17
And i want to run this sql
Insert into table names(name,age) values ("Chriss",15)//should be inserted
Insert into table names(name,age) values ("Mark",17)// should be ignored
Insert into table names(name,age) values ("Andrea",20) //should be inserted
So how can I ignore second insert query
Create a constraint that demands NAME and Age to be unique in the table.
ALTER TABLE `tablename` ADD UNIQUE `unique_index`(`NAME`, `Age`);
You would either need to Add UNIQUE constraint or check the data at the run time (if you don't have a permission to change table schema):
ALTER TABLE `Table_name`
ADD UNIQUE INDEX (`NAME`, `AGE`);
You can use:
INSERT INTO names(name,age)
SELECT * FROM (SELECT 'Chriss', 15) AS tmp
WHERE NOT EXISTS (
SELECT name FROM names WHERE name = 'Chriss' AND age = 15
) LIMIT 1;
An other way is just make the columns name and age UNIQUE so the query fails.
Change your query to this:
Insert into table names(name,age)
SELECT "Chriss",15 WHERE NOT EXISTS (SELECT 1 FROM names WHERE `name` = "Chriss");
Insert into table names(name,age)
SELECT "Mark",17 WHERE NOT EXISTS (SELECT 1 FROM names WHERE `name` = "Mark");
Insert into table names(name,age)
SELECT "Andrea",20 WHERE NOT EXISTS (SELECT 1 FROM names WHERE `name` = "Andrea");
First create a unique constraint for the columns NAME and Age:
ALTER TABLE names ADD UNIQUE un_name_age (`NAME`, `Age`);
and then use INSERT IGNORE to insert the rows:
Insert ignore into names(name,age) values
("Chriss",15),
("Mark",17),
("Andrea",20);
So if you try to insert a duplicate name the error will just be ignored and the statement will continue with the next row to insert.
See the demo.
Result:
| ID | NAME | Age |
| --- | ------ | --- |
| 1 | Paula | 20 |
| 2 | Mark | 17 |
| 3 | Chriss | 15 |
| 4 | Andrea | 20 |
I have a table with three columns, I want copy/paste all three columns within the same table, however, of the three columns, I want to update two columns with new data specific for that day while keeping one column the same. For the following table:
ticket_number | book_id | log_id
------------- | ------- | ------
1 | 1 | 120
12 | 2 | 120
23 | 3 | 120
I want to:
1) Copy all columns and paste into the same table
2) change the ticket_number column with new data for that day (e.g. 2, 13, 25) as well as the log_id column with the id for the current day (e.g. 121), while keeping book_id column the same.
I have tried with no avail:
INSERT INTO ticket (ticket_number, book_id, log_id) SELECT (2,13,24), (book_id), (121) FROM ticket;
This the schema for reference
Your SELECT query needs to return the rows that you want to insert.
UPDATE: You can use a separate table, which might be easier. Something like this:
CREATE TABLE id_map (
old_ticket_number NUMBER,
new_ticket_number NUMBER
);
You could insert the values into this table.
You can then use this query:
INSERT INTO ticket (ticket_number, book_id, log_id)
SELECT
m.new_ticket_number,
t.book_id,
121
FROM ticket t
INNER JOIN id_map m ON t.ticket_number = m.old_ticket_number;
Does this so what you're looking for?
I am using MySQL. I want to insert value's result from groupby of datetime to specific column (using where, maybe). Let say:
I have two tables (a, b). In table a, I want to get how many total records during a hour (which I have datetime column), then the result will insert into table b, but in specific ID (there is already exist ID's value).
This is my error code:
INSERT INTO b(value)
WHERE ID=15
SELECT DAY COUNT(*)
FROM a
WHERE date >= '2015-09-19 00:00:00' AND date < '2015-09-19 00:59:59'
GROUP BY DAY(date),HOUR(date);";
Is that possible I make a query from this case?
Thank you very much for any reply!
Schema
create table tA
( id int auto_increment primary key,
theDate datetime not null,
-- other stuff
key(theDate) -- make it snappy fast
);
create table tB
( myId int primary key, -- by definition PK is not null
someCol int not null
);
-- truncate table tA;
-- truncate table tB;
insert tA(theDate) values
('2015-09-19'),
('2015-09-19 00:24:21'),
('2015-09-19 07:24:21'),
('2015-09-20 00:00:00');
insert tB(myId,someCol) values (15,-1); -- (-1) just for the heck of it
insert tB(myId,someCol) values (16,-1); -- (-1) just for the heck of it
The Query
update tB
set someCol=(select count(*) from tA where theDate between '2015-09-19 00:00:00' and '2015-09-19 00:59:59')
where tB.myId=15;
The Results
select * from tB;
+------+---------+
| myId | someCol |
+------+---------+
| 15 | 2 |
| 16 | -1 |
+------+---------+
only myId=15 is touched.
I have datewise tables created with date as part of the table name.
ex. data_02272015, data_02282015 (name format is data_<mmddyyyy>). All the tables have the same schema.
Now, The tables have a datetime column TransactionDate. I need to get all the records by querying against this column. One table stores 24 hr data of the corresponding day. So, if I query with date 2015-02-28 xx:xx:xx, I can just query the table data_02282015. But, if I want to query with date 2015-02-27 xx:xx:xx, I have to consider both the tables data_02282015 and data_02272015.
I can get the union like this:
SELECT * FROM data_02272015
UNION
SELECT * FROM data_02282015;
But the problem is I also need to check whether either of the table exists. So if data_02282015 does not exists, the query fails. Is there a way with which query will return the records from the table(s) that exists.
So,
If both table exists, then it will return union of records of both the tables.
If either table does not exists, then it will return records for existing table only.
If both tables does not exists, empty resultset.
I tried things like:
SELECT IF( EXISTS(SELECT 1 FROM data_02282015), (SELECT * FROM data_02282015), 0)
...
But it didn't worked.
If I understand the question correctly, you need a FULL JOIN :
CREATE TABLE two
( val INTEGER NOT NULL PRIMARY KEY
, txt varchar
);
INSERT INTO two(val,txt) VALUES
(0,'zero'),(2,'two'),(4,'four'),(6,'six'),(8,'eight'),(10,'ten');
CREATE TABLE three
( val INTEGER NOT NULL PRIMARY KEY
, txt varchar
);
INSERT INTO three(val,txt) VALUES
(0,'zero'),(3,'three'),(6,'six'),(9,'nine');
SELECT *
FROM two t2
FULL JOIN three t3 ON t2.val = t3.val
ORDER BY COALESCE(t2.val , t3.val)
;
Result:
CREATE TABLE
INSERT 0 6
CREATE TABLE
INSERT 0 4
val | txt | val | txt
-----+-------+-----+-------
0 | zero | 0 | zero
2 | two | |
| | 3 | three
4 | four | |
6 | six | 6 | six
8 | eight | |
| | 9 | nine
10 | ten | |
(8 rows)
Try this script. As a complete solution, you could use the following embedded in a stored procedure, replacing id column with all your needed columns.
-- temp table that will collect results
declare #tempResults table (id int)
-- Your min and max dates to iterate between
declare #dateParamStart datetime
set #dateParamStart = '2015-02-25'
declare #dateParamEnd datetime
set #dateParamEnd = '2015-02-28'
-- table name using different dates
declare #currTblName nchar(13)
while #dateParamStart < #dateParamEnd
begin
-- set table name with current date
SELECT #currTblName = 'data_' + REPLACE(CONVERT(VARCHAR(10), #dateParamStart, 101), '/', '')
SELECT #currTblName -- show current table
-- if table exists, make query to insert into temp table
if OBJECT_ID (#currTblName, N'U') IS NOT NULL
begin
print ('table ' + #currTblName + 'exists')
execute ('insert into #tempResults select id from ' + #currTblName)
end
-- set next date
set #dateParamStart = dateadd(day, 1, #dateParamStart)
end
-- get your results.
-- Use distinct to act as a union if rows can be the same between tables.
select distinct * from #tempResults