Why is my procedure populating separate rows? - mysql

My stored procedure is populating different rows and I need it to populate a single row. I have tried adding in some where clauses but that breaks it. Any help is appreciated!
DELIMITER //
CREATE PROCEDURE Populate()
BEGIN
insert into log(NoEmp) (select count(empid) from emp);
insert into log(NoDept) (select count(deptid) from dept);
insert into log(LocReg1) (select count(regionid) from region where regionid=1);
insert into log(LocReg2) (select count(regionid) from region where regionid=2);
insert into log(LocReg3) (select count(regionid) from region where regionid=3);
insert into log(TotSales) (select sum(salesamt) from sales);
insert into log(AvgSaleMo) (select TotSales/(24) from log);
insert into log(AvgSaleYr) (select TotSales/(2) from log);
insert into log(logdate) (select NOW());
END //
DELIMITER ;

Every time you INSERT it creates a new row (unless you use the ON DUPLICATE KEY UPDATE clause).
If you want to insert a single row, use a single INSERT with multiple columns and values.
INSERT INTO log (NoEmp, NoDept, LocReg1, LocReg2, LocReg3, TotSales, AvgSaleMo, AvgSaleYr, logdate)
VALUES (
(select count(empid) from emp),
(select count(deptid) from dept),
(select count(regionid) from region where regionid=1),
(select count(regionid) from region where regionid=2),
(select count(regionid) from region where regionid=3),
(select sum(salesamt) from sales),
(select sum(salesamt)/(24) from sales),
(select sum(salesamt)/(2) from sales),
NOW()
);

Related

Create trigger to increase value when found duplicate

I need to make trigger to increase the 2nd digit when the new value found to be a duplicate.
For Instance, I have a unique filed with 10 digits value. I want when someone insert same number it increase the second left digit like 0100012345. How I can do that? Thank you.
FirstName LastName Code
Houssam Salim 0100012345 to be 0200012345
Try this
I have found a solution with instead off trigger
'/*
CREATE TABLE [Employee1]
(
[id] VARCHAR(20) PRIMARY KEY,
[name] VARCHAR(50)
)
CREATE TRIGGER AutoIncrement_Trigger
ON [Employee1]
instead OF INSERT
AS
BEGIN
DECLARE #ch CHAR
DECLARE #num INT
IF EXISTS (SELECT 1
FROM Employee1 e
JOIN inserted i
ON i.id = e.id)
BEGIN
SET #num=(SELECT max(CONVERT(INT, substring(e.id, 1, 2))) + 1
FROM employee1 e
JOIN inserted i
ON substring(e.id, 3, len(e.id)) = substring(i.id, 3, len(i.id)))
INSERT INTO [Employee1]
(id,
name)
SELECT '0' + CONVERT(VARCHAR(10), #num)
+ substring(i.id, 3, len(i.id)),
e.name
FROM Employee1 e
JOIN inserted i
ON i.id = e.id
END
ELSE
BEGIN
INSERT INTO [Employee1]
(id,
name)
SELECT inserted.id,
inserted.name
FROM inserted
END
END
*/
INSERT INTO [Employee1]
VALUES ('0100012345',
'John')
SELECT *
FROM [Employee1]
INSERT INTO [Employee1]
VALUES ('0100012345',
'John')
SELECT *
FROM [Employee1]
'

Rows as columns keeping the value of that row

I m working on sql server and stucked with how can I get the desired output.
I have the below as the source table.
and I want the desired output as below.
Here is the Query to have source table.
DECLARE #Temp TABLE(Capacity INT,CDate DATE,Name NVARCHAR(100))
INSERT INTO #Temp VALUES (1,'4/14/2014','M24')
INSERT INTO #Temp VALUES (1,'4/15/2014','M22')
INSERT INTO #Temp VALUES (1,'4/14/2014','M24')
INSERT INTO #Temp VALUES (1,'4/15/2014',NULL)
INSERT INTO #Temp VALUES (2,'4/14/2014','F67')
INSERT INTO #Temp VALUES (2,'4/15/2014','F31')
INSERT INTO #Temp VALUES (3,'4/14/2014','M53')
SELECT * FROM #Temp
Can anyone help me, please.
You can use the PIVOT function to get the result but since you need to return multiple rows for each Capacity, you will want to use a windowing function like row_number() that will generate a unique sequence for each Capacity and CDate combination:
SELECT Capacity, [2014-04-14], [2014-04-15]
FROM
(
SELECT Capacity,
CDate,
Name,
row_number() over(partition by capacity, cdate
order by capacity) seq
FROM #Temp
) d
PIVOT
(
MAX(name)
FOR CDate IN ([2014-04-14], [2014-04-15])
) piv
ORDER BY Capacity;
See SQL Fiddle with Demo

how to get last modified column name from mysql

Is it possible to get a particular updated column name from a record?
if so, please help me. since i am creating a history table to store a updated column and their values from rest of the tables.
DROP TRIGGER IF EXISTS testing.hisupdate;
CREATE TRIGGER testing.hisupdate AFTER
UPDATE ON testing.emp
FOR EACH ROW
INSERT INTO testing.history (`id`,`revision_id`,`trx_code`, `trx_method`, `column_name`, `old_value`, `new_value`, `trx_timestamp`, `user_id`)
SELECT
(SELECT emp_id
FROM testing.emp
ORDER BY last_update DESC LIMIT 1),
(SELECT p.revision_id
FROM testing.history AS p
WHERE p.id=
(SELECT emp_id
FROM testing.emp
ORDER BY last_update DESC LIMIT 1)
ORDER BY trx_timestamp DESC LIMIT 1) + 1, 'updt', 'update','null',
(SELECT p.new_value
FROM testing.history AS p
WHERE p.id=
(SELECT emp_id
FROM testing.emp
ORDER BY last_update DESC LIMIT 1)
ORDER BY trx_timestamp DESC LIMIT 1), concat(p.emp_id,"/",p.emp_name,"/",p.salary,"/") AS new_value,
NOW(),
'101'
FROM testing.emp AS p
WHERE p.emp_id = new.emp_id;
i have created trigger but searching for a sub query for last updated column name..
thanks in advance.
Try this code...
create table sales(orderno INT, sale INT,empsalary int, ts TIMESTAMP);
create table history(updated varchar(20), oldvalue INT,newvalue INT);
INSERT INTO sales (orderno,sale,empsalary) VALUES(1,700,7000);
INSERT INTO sales (orderno,sale,empsalary) VALUES(2,800,8000);
INSERT INTO sales (orderno,sale,empsalary) VALUES(3,900,9000);
DROP TRIGGER test.instrigger;
DELIMITER ///
CREATE TRIGGER test.instrigger AFTER UPDATE ON sales
FOR EACH ROW
BEGIN
IF NEW.sale <> OLD.sale THEN
INSERT INTO history (updated, oldvalue, newvalue) VALUES('sale', OLD.sale,NEW.sale);
END IF;
IF NEW.empsalary <> OLD.empsalary THEN
INSERT INTO history (updated, oldvalue, newvalue) VALUES('empsalary', OLD.empsalary,NEW.empsalary);
END IF;
END;
///
DELIMITER ;

Insert query based on number of rows

I want a query to insert a row into a table I know it is simple but the scenario is the table should not have more than 5 rows. If table has more than five rows I need to remove the old row(Or replace with new row ) (Based on the insert time stamp) then i need to insert a new row.If number of rows less than count 5 then i can directly insert a row.
Please share me the query.
How about something like this.
declare #count int
SELECT #count=COUNT(*)
from EP_ANSWERS
IF (#count<5)
// DO your insert here
ELSE
DELETE FROM TABLE
WHERE inserttimestamp = (SELECT x.inserttimestamp
FROM (SELECT MAX(t.inserttimestamp) AS inserttimestamp
FROM TABLE t) x)
// DO your insert here
If it is impossible for the table to have more than 5 rows:
DELETE FROM yourtable
WHERE 5 <= (SELECT COUNT(*) FROM yourtable)
AND yourtimestamp = (SELECT MIN(yourtimestamp) FROM yourtable)
;
INSERT INTO yourtable ...
;
If it is possible for the table to have more than 5 rows:
DELETE FROM yourtable
WHERE 5 <= (SELECT COUNT(*) FROM yourtable)
AND yourtimestamp NOT IN (SELECT yourtimestamp
FROM yourtable
ORDER BY yourtimestamp DESC
LIMIT 4)
;
INSERT INTO yourtable ...
;
It sounds like you want to put a trigger on the table to maintain this rule, in MySQL the something like this should work
CREATE TRIGGER trg__my_table__limit_rows
BEFORE INSERT
ON my_table
FOR EACH ROW
BEGIN
IF ((SELECT COUNT(1) FROM my_table) = 5)
BEGIN
DELETE FROM my_table
WHERE id = (SELECT MIN(id) FROM my_table) -- change this to fit your logic for which record should be removed
END
END
Some of the code here is in pseudo (you didn't wrote your schema), but i wrote where you need to complete your own code.
DECLARE #NumberOfRowsToInsert INT = -- select from the data you want to insert
DECLARE #MaxNumberOfRows INT = 5
DECLARE #NumberOfExistingRows INT
DECLARE #Query VARCHAR(MAX) = 'SELECT TOP #rows id FROM SomeTable ORDER BY createdDate ASC'
SELECT #NumberOfExistingRows = COUNT(*)
FROM SomeTable
SET #Query = REPLACE(#Query,'#rows',
CAST(#NumberOfRowsToInsert - (#MaxNumberOfRows - #NumberOfExistingRows))) AS VARCHAR(1))
CREATE TABLE #IdsToDelete(id INT PRIMARY KEY)
INSERT INTO #IdsToDelete
EXEC(#Query)
DELETE FROM SomeTable
WHERE id IN (SELECT * FROM #IdsToDelete)
-- insert here..

Last 5 related records for multiple records

I have a MySQL database with a structure like this...
Site has many Sensors
Sensors has many SensorReadings
I want to get all Sensors for a Site and the last 5 SensorReadings for all those Sensors. I suspect I'm going to have to do something with a stored procedure and temporary tables (if they even exist in MySQL.
Possibly Something like...
SELECT reading,
date
FROM (select sensor_id,
reading,
date,
#num := if(#sensor_id = sensor_id, #num + 1, 1) as row_number,
#sensor_id := sensor_id as dummy
from sensor_readings
order by sensor_id,
date desc) T
WHERE row_number<=5
Please give your actual table structure(s) in your question.
Full example using MySQL variables. For brevity, this displays the top 2 readings per sensor.
drop table if exists Sensors;
create table Sensors (Id int);
insert Sensors (id) values (1), (2), (3);
drop table if exists SensorReadings;
create table SensorReadings (SensorId int, RecordDate date);
insert SensorReadings (SensorId, RecordDate) values
(1, '2011-01-01'),
(1, '2011-01-02'),
(1, '2011-01-03'),
(2, '2011-01-01'),
(2, '2011-01-02'),
(2, '2011-01-03');
set #num = -1;
set #SensorId = -1;
select *
from Sensors s
join (
select *
, #num := if(#SensorId = SensorId, #num + 1, 1) as rn
, #SensorId := SensorId
from SensorReadings sr
order by
SensorId
, RecordDate desc
) as numbered
on numbered.SensorId = s.Id
where numbered.rn < 3;
Based on Andomar dump
select * from SensorReadings as t1
where (select count(*) from SensorReadings as t2
where t1.sensorid = t2.sensorid and t2.recordDate > t1.recordDate) <2