mysql: find newest non null values - mysql

I have a huge table with 100 fields. Each row is timestamped. I want to find the latest non null value for all columns. I'm using MySql 5.6 InnoDB
e.g.
create table tester(
pub_id int,
pub_name varchar(20),
pub_city varchar(20),
country varchar(20),
no_of_branch varchar(20),
estd datetime
);
insert into tester (pub_id, pub_name, pub_city, country, estd)
values
(1, 'a', 'xyz', 'abcity' , 'a', '1970-01-01 00:00:01'),
(2, 'a', 'xyz', '' , 'a', '1971-01-01 00:00:01'),
(3, 'a', 'xyz', 'abcity1', 'b', '1972-01-01 00:00:01'),
(4, 'a', 'xyz', '' , 'a', '1973-01-01 00:00:01'),
(5, 'a', 'xyz', 'abcity2', '' , '1974-01-01 00:00:01'),
(6, 'b', 'lmn', 'abcity' , 'a', '1974-01-01 00:00:01'),
(7, 'b', 'xyz', '' , 'a', '1975-01-01 00:00:01'),
(8, 'b', 'sdf', 'abcity1', 'b', '1976-01-01 00:00:01'),
(9, 'b', '' , '' , 'a', '1977-01-01 00:00:01'),
(10, 'b', '' , 'abcity2', '' , '1978-01-01 00:00:01');
I want to query that would give me:
'a', 'xyz', 'abcity2', 'a'
'b', 'sdf', 'abcity2', 'b'
I don't want to use a query where i find empty values for each column of the table individually and then take a join as this would be a very cumbersome task given that my actual table has 100 columns.
I have searched for a solution for the past of couple of ours and found nothing. ANy help would be greatly appreciated.
Thanks

This might be the "tricky" way you are looking for.
First create a twin table (tester2) to receive the aggregated data. This new table must have a primary key on pub_name and all the columns you want to aggregate. Then do an INSERT INTO ON DUPLICATE KEY UPDATE. This query will basically rebuild the tester table but without duplicate and with aggregated data. In fact something like this :
insert into tester2 (pub_name, pub_city, country, no_of_branch)
select pub_name, pub_city, country, no_of_branch FROM tester order by estd desc
on duplicate key
update
pub_city = coalesce(tester2.pub_city,tester.pub_city),
country = coalesce(tester2.country,tester.country),
no_of_branch = coalesce(tester2.no_of_branch,tester.no_of_branch)
The content of tester2 will be :
PUB_NAME PUB_CITY COUNTRY NO_OF_BRANCH
a xyz abcity2 a
b sdf abcity2 a
Have a look the DB Fiddle.
Note : I assume you mean real NULL values and not empty string like the sample you provided.

Related

I am receiving duplicate column name, but based on values. When i change the value, there is no error

I am trying to use this query, but when there are the same value in different columns, I receive this error:
1060 - Duplicate column name "123"
For example here:
INSERT INTO chiro(in_out,chirocov,chirocov2,chiroded,chiromet,
chirocovp,chirooop,chirooopmet,chirooopcp,
chirovisit,chirouse,chiromax,chirodedapply,
chironum1,chironum2)
SELECT * FROM (SELECT 'in', 'no','individual','123','123','20',
'213','21243','10','14','5','2000','yes',
'0','1') AS tmp
WHERE NOT EXISTS (SELECT in_out,chirocov,chirocov2,
chiroded,chiromet,chirocovp,chirooop,
chirooopmet,chirooopcp, chirovisit,chirouse,
chiromax,chirodedapply,chironum1,chironum2
FROM chiro
WHERE chirocov='no'
AND chirocov2='individual'
AND chiroded='123'
AND chiromet='123'
AND chirocovp='20'
AND chirooop='213'
AND chirooopmet='213'
AND chirooopcp='10'
AND chirovisit='14'
AND chirouse='5'
AND chiromax='2000'
AND chirodedapply='yes'
AND chironum1='0'
AND chironum2='1')
LIMIT 1
But when i change the value, there won"t be any errors. like:
INSERT INTO chiro(in_out,chirocov,chirocov2,chiroded,
chiromet,chirocovp,chirooop,chirooopmet,
chirooopcp, chirovisit,chirouse,chiromax,
chirodedapply,chironum1,chironum2)
SELECT * FROM (SELECT 'in', 'no','individual','123','231','20',
'213','21243','10','14','5','2000',
'yes', '0','1') AS tmp
WHERE NOT EXISTS (SELECT in_out,chirocov,chirocov2,
chiroded,chiromet,chirocovp,chirooop,
chirooopmet,chirooopcp, chirovisit,chirouse,
chiromax,chirodedapply,chironum1,chironum2
FROM chiro
WHERE chirocov='no'
AND chirocov2='individual'
AND chiroded='123'
AND chiromet='123'
AND chirocovp='20'
AND chirooop='213'
AND chirooopmet='213'
AND chirooopcp='10'
AND chirovisit='14'
AND chirouse='5'
AND chiromax='2000'
AND chirodedapply='yes'
AND chironum1='0'
AND chironum2='1')
LIMIT 1
Could you help me and let me know what I am doing wrong?
Just remove the outer SELECT from:
SELECT * FROM (SELECT 'in', 'no','individual','123','123','20',
'213','21243','10','14','5','2000','yes',
'0','1') AS tmp
because it retrieves all the unnamed columns from the inner select with names that are their values, so there are 2 columns with the same name 123.
See a simplified demo of the problem.
Use this:
INSERT INTO chiro(
in_out, chirocov, chirocov2, chiroded, chiromet, chirocovp, chirooop, chirooopmet, chirooopcp,
chirovisit, chirouse, chiromax, chirodedapply, chironum1, chironum2
)
SELECT 'in', 'no', 'individual', '123', '123', '20', '213', '21243', '10', '14', '5', '2000', 'yes', '0', '1'
WHERE NOT EXISTS(
SELECT in_out, chirocov, chirocov2, chiroded, chiromet, chirocovp, chirooop, chirooopmet, chirooopcp,
chirovisit, chirouse, chiromax, chirodedapply, chironum1, chironum2
FROM chiro
WHERE chirocov='no' AND chirocov2='individual' AND chiroded='123' AND chiromet='123' AND chirocovp='20'
AND chirooop='213' AND chirooopmet='213' AND chirooopcp='10' AND chirovisit='14' AND chirouse='5'
AND chiromax='2000' AND chirodedapply='yes' AND chironum1='0' AND chironum2='1'
)
Also LIMIT 1 is not necessary.

My code is only returning two of the five entries I need, how can I fix this problem?

I am trying to create a list of employees showing their first name, hire date, and the city where they work. There are five employees listed but when I run my problem it only returns the first two from the location data entry.
Shown first is my employee data entered. When I run a select * statement for this table everything appears as it should. The problem comes when I try to run the second script shown, where it only shows the first two entries from the employee table.
first
INSERT INTO `salon`.`employee`
(`employee_id`,
`first_name`,
`last_name`,
`title`,
`hire_date`,
`termination_date`,
`email`,
`phone`,
`location_id`,
`manager_id`)
VALUES
(1,
'Jenny',
'Jensen',
'Owner',
'2013-06-15',
NULL,
'jensenj#salon.com',
2081112222,
1,
NULL),
(2,
'Haley',
'Lopez',
'Assistant Manager',
'2013-08-23',
NULL,
'lopezh#salon.com',
2083334444,
1,
1),
(3,
'Robert',
'Green',
'Associate',
'2014-01-03',
NULL,
'greenr#salon.com',
2085556666,
1,
2),
(4,
'Olive',
'Adams',
'Manager',
'2015-07-12',
NULL,
'adamso#salon.com',
2087778888,
2,
1),
(5,
'Julie',
'Davis',
'Associate',
'2015-10-20',
NULL,
'davisj#salon.com',
2089990000,
2,
4);
second script
SELECT employee.first_name, hire_date, location.city
FROM employee
JOIN location ON employee.employee_id = location.location_id

MySQL - return values in order provided

In MySQL, I run a lot of SELECT statements with IN clauses. Sometimes I want to see the output table ordered by the order of values that I used in the IN clause, rather than alpha/numerical.
If I ran
SELECT id FROM x
WHERE id IN ('1', '3', '2', '0')
I would want output 1, 3, 2, 0, not 0, 1, 2, 3.
Is there a way to effect this?
Thanks!
With the following query you should get what you want:
SELECT id FROM x WHERE id IN ('1', '3', '2', '0') ORDER BY FIELD(id, '1', '3', '2', '0')
From the MySQL specification about FIELD():
Returns the index (position) of str in the str1, str2, str3, ... list. Returns 0 if str is not found.
http://dev.mysql.com/doc/refman/5.7/en/string-functions.html#function_field

Error in Mysql query Insert or update

I am a little bit desesperate with this query, I can't find my fault:
INSERT INTO device (
Device_UUID,
Model,
Manufacturer,
Latitude,
Longitude,
Type,
Registration_Date,
Status,
API_Source)
values (
'WW',
'a',
'v',
'0.00',
'0.00',
'BUS',
'2014-01-01 12:11:11',
'1',
'R')
ON DUPLICATE KEY UPDATE
Model = "wwww",
Manufacturer = "bbbbb",
Registration_Date = "2014-01-01 12:11:11";
All fields are String, even latitud and longitude
Type is a keyword. Try to put Type inside some ".

MySQL. Counting just a part of my column value

I have a question relating tables in MySQL. To understand this better I'd rather show you. I have the following table:
CREATE TABLE IF NOT EXISTS `tip_masina` (
`id_tip` int(11) NOT NULL AUTO_INCREMENT,
`marca` varchar(40) NOT NULL,
`pret` int(11) NOT NULL,
PRIMARY KEY (`id_tip`),
UNIQUE KEY `marca` (`marca`)
) ENGINE=InnoDB DEFAULT CHARSET=latin1 AUTO_INCREMENT=16 ;
INSERT INTO `tip_masina` (`id_tip`, `marca`, `pret`) VALUES
(1, 'Chevrolet Impala', 8000),
(2, 'Chevrolet Camaro', 10000),
(3, 'Chevrolet Tahoe', 13000),
(4, 'Chevrolet Suburban', 12500),
(5, 'Chevrolet Cobalt', 4000),
(6, 'Dodge Charger', 14000),
(7, 'Dodge Avenger', 9000),
(8, 'Dodge Challenger', 6500),
(9, 'Dodge Dart', 3500),
(10, 'Dodge Durango', 3000),
(11, 'Ford Mustang', 7500),
(12, 'Ford Crown Victoria', 5000),
(13, 'Ford Focus', 4300),
(14, 'Ford Fiesta', 3700),
(15, 'Ford Escort', 1000);
What I want out of this table is to display the vehicle type and the number of vehicles, like:
marca | no_of_vehicles
Chevrolet 5
Dodge 5
Ford 5
Is there any way to do this without splitting the column marca in two columns?
Here is an easy way, using substring_index():
select substring_index(marca, ' ', 1) as marca, count(*)
from tip_masina
group by substring_index(marca, ' ', 1);
It might be better to split 'marca' into two columns so that it would be easier to find what you want. You won't need any special functions then (as e.g. substring_index).
EDIT:
You can use following code:
EDIT2:
Now it works (tested on mysql workbench with your queries creating table):
START TRANSACTION;
ALTER TABLE tip_masina ADD model VARCHAR(60) AFTER marca;
ALTER TABLE tip_masina CHANGE marca company VARCHAR(60);
UPDATE tip_masina SET model = SUBSTRING_INDEX(company, ' ', -1);
ALTER TABLE tip_masina DROP INDEX marca;
UPDATE tip_masina SET company = SUBSTRING_INDEX(company, ' ', 1);
SELECT * FROM tip_masina;