I have a table with the following fields.
Account,DeviceID,timestamp,odometer
The first three fields are Primary Key
Some deviceID are cloned in different account.
Now those clones have corrupted odometer.
Account,DeviceID,timestamp,odometer
1 A 001 145
1 A 002 147
1 A 003 148
2 A 001 145
2 A 002 NULL
2 A 003 0
Device A in account 2 is the clon of device A in account 1.
So, how I can clone the odometer values from account 1 and device A to the same timestamp of device A in account 2?
I need to create a store procedure that I can feed whit three paramaters, OriginalAccount, CloneAccount, DeviceID, to fix one by one all the clones.
Edit:
If I have the following data
+---------+-----------+-----------+----------+
| account | device_id | timestamp | odometer |
+---------+-----------+-----------+----------+
| 1 | A | 001 | 145 |
| 1 | A | 002 | 147 |
| 1 | A | 003 | 148 |
| 2 | A | 001 | 145 |
| 2 | A | 002 | NULL |
| 2 | A | 003 | 0 |
After call the store procedure the table must look like this
+---------+-----------+-----------+----------+
| account | device_id | timestamp | odometer |
+---------+-----------+-----------+----------+
| 1 | A | 001 | 145 |
| 1 | A | 002 | 147 |
| 1 | A | 003 | 148 |
| 2 | A | 001 | 145 |
| 2 | A | 002 | 147 |
| 2 | A | 003 | 148 |
Schema
create table thing7
( account int not null,
device_id varchar(10) not null,
`timestamp` int(3) zerofill not null, -- not a great column name btw (it is a keyword, not a reserved word)
odometer int null,
primary key(account,device_id,timestamp)
);
insert thing7(account,device_id,timestamp,odometer) values
(1,'A',1,145),
(1,'A',2,147),
(1,'A',3,148),
(2,'A',1,145),
(2,'A',2,NULL),
(2,'A',3,0);
Look at Data at start:
select * from thing7;
+---------+-----------+-----------+----------+
| account | device_id | timestamp | odometer |
+---------+-----------+-----------+----------+
| 1 | A | 001 | 145 |
| 1 | A | 002 | 147 |
| 1 | A | 003 | 148 |
| 2 | A | 001 | 145 |
| 2 | A | 002 | NULL |
| 2 | A | 003 | 0 |
+---------+-----------+-----------+----------+
Stored Procedure
drop procedure if exists cloneIt;
DELIMITER $$
create procedure cloneIt
( srcAcct int, -- the data of the source to be copied
destAcct int, -- the target to receive it
device varchar(10)
)
BEGIN
-- clean out any old junk in case src does not match dest
-- this is due to edge conditions where dest has more rows than src, and you said you want a clone
delete from thing7 where account=destAcct and device_id=device;
-- now clone it
insert thing7(account,device_id,`timestamp`,odometer)
select destAcct,device_id,`timestamp`,odometer
from thing7
where account=srcAcct and device_id=device;
END
$$
DELIMITER ;
Delimiters set up wrong can waste hours. Have them or look into their use.
clone 1 to 7:
call cloneIt(1,7,'A');
Test one edge condition: dest has more info than src
insert thing7(account,device_id,timestamp,odometer) values
(14,'A',1,145),
(14,'A',2,147),
(14,'A',3,148),
(14,'A',4,199);
14 now had 4 rows
call cloneIt(1,14,'A');
Look at results:
select * from thing7;
+---------+-----------+-----------+----------+
| account | device_id | timestamp | odometer |
+---------+-----------+-----------+----------+
| 1 | A | 001 | 145 |
| 1 | A | 002 | 147 |
| 1 | A | 003 | 148 |
| 2 | A | 001 | 145 |
| 2 | A | 002 | NULL |
| 2 | A | 003 | 0 |
| 7 | A | 001 | 145 |
| 7 | A | 002 | 147 |
| 7 | A | 003 | 148 |
| 14 | A | 001 | 145 |
| 14 | A | 002 | 147 |
| 14 | A | 003 | 148 |
+---------+-----------+-----------+----------+
cloneIt works. It creates exact clones
Related
mysql> select * from ATRs;
+-----+-------------+---------------+-------+----------+
| Id | Name_ | Team | Goals | Trophies |
+-----+-------------+---------------+-------+----------+
| 110 | Messi | Barcelona | 699 | 0 |
| 107 | Ronaldo | Juventus | 60 | 0 |
| 107 | Ronaldo | Real Madrid | 60 | 0 |
| 109 | Lewandowski | Bayern Munich | 400 | 10 |
| 109 | Lewansowski | Dortmund | 88 | 4 |
| 210 | Neymar | Barcelona | 121 | 9 |
| 210 | Neymar | Paris | 48 | 1 |
+-----+-------------+---------------+-------+----------+
7 rows in set (0.00 sec)
This is my table right now
alter table ATRs change Name_ Name varchar(22);
After this command the server doesn't respond at all and whatever i write after that is just treated as a plain text.
Please rename column rather than changing
ALTER TABLE ATRs RENAME COLUMN Name_ TO Name;
NAME is a keyword. Try using backticks.
alter table ATRs change `Name_` `Name` varchar(22);
I have a table called transactions that looks like this:
transactions:
| id | PartNumber | Quantity |
I know that I can use the COUNT property in MySQL, which would give me the the duplicate part numbers in a new column called total_quantity:
SELECT COUNT(transactions.id) AS total_quantity
FROM transactions
GROUP BY transactions.PartNumber
However, now I already have an existing quantity column and want to compute a new count quantity taking into account the previous one as well and updating it in the existing quantity column
What's the most efficient way of doing this?
For example: I want to go from this:
transactions
| id | PartNumber | Quantity |
| 1 | 123 | 1 |
| 2 | 124 | 2 |
| 3 | 125 | 2 |
| 4 | 124 | 2 |
| 5 | 124 | 3 |
| 6 | 126 | 4 |
| 7 | 125 | 1 |
| 8 | 127 | 2 |
To this:
transactions
| id | PartNumber | Quantity |
| 1 | 123 | 1 |
| 2 | 124 | 7 |
| 3 | 125 | 3 |
| 4 | 126 | 4 |
| 5 | 127 | 2 |
You can use this sql request :
SELECT PartNumber, sum(Quantity) as 'SumQuantity' FROM transactions GROUP BY PartNumber
It will gives you sometings like this :
transactions
| PartNumber | SumQuantity |
| 123 | 1 |
| 124 | 7 |
| 125 | 3 |
| 126 | 4 |
| 127 | 2 |
You can find a code sample on SQL Fiddle
A query returns data in the following format
-----------------------------------------
| CustID | ProdID | Date | Amount |
-----------------------------------------
| 001 | 444 | 12/09/2017 | £234 |
| 001 | 524 | .... | £234 |
| 004 | 444 | .... | £321 |
| 008 | 523 | ..... | £299 |
| 008 | 444 | ... | £299 |
.......
As shown above, there are often multiple records for CustID (one per ProdID). The problem is that the amount in the last column is the total for both 444 and 524 (in the case of Customer 001). Additionally, the ProdId can contain duplicates as the products are the same for many customers.
In other words, in Excel speak, I'm trying to remove duplicates from column CustID.
I'd like it to be:
-------------------
| CustID | Amount |
-------------------
| 001 | £234 |
| 004 | £321 |
| 008 | £299 |
I've got a MySQL table that looks like this:
recordID | peopleID | AddressTypeID | Address | ActiveInd
10 | 102 | 1 | 4th Ave | 1
11 | 102 | 3 | 4th Ave | 1
12 | 203 | 3 | 5th Ave | 1
I'm trying to get a record at the peopleID level wherever AddressTypeID = 1 but if that doesn't exist, then get a record for AddressTypeID = 3.
So result set would be this:
recordID | peopleID | AddressTypeID | Address | ActiveInd
10 | 102 | 1 | 4th Ave | 1
12 | 203 | 3 | 5th Ave | 1
I don't think coalesce is the answer, and thought of trying a large case statement, but I would get duplicate records using case, right?
A modified version of my answer here (which is dealing with failover languages):
select t.*
from mytable t
left join mytable t1
on t1.peopleID = t.peopleID
and t1.AddressTypeID = 1
and t.AddressTypeID = 3
where t.AddressTypeID in (1, 3)
and t1.recordID is null
I changed the sample data to cover more cases:
| recordID | peopleID | AddressTypeID | Address | ActiveInd |
|----------|----------|---------------|---------|-----------|
| 10 | 102 | 1 | 4th Ave | 1 |
| 11 | 102 | 3 | 4th Ave | 1 |
| 12 | 203 | 3 | 5th Ave | 1 |
| 13 | 304 | 1 | 6th Ave | 1 |
| 14 | 405 | 2 | 7th Ave | 1 |
And the result is:
| recordID | peopleID | AddressTypeID | Address | ActiveInd |
|----------|----------|---------------|---------|-----------|
| 10 | 102 | 1 | 4th Ave | 1 |
| 12 | 203 | 3 | 5th Ave | 1 |
| 13 | 304 | 1 | 6th Ave | 1 |
Demo: http://sqlfiddle.com/#!9/d48b92/2
I have a database with this table(rating)..
+---------+-------------+----------+------+------------+
| rate_id | reviewer_id | movie_id | rate | date1 |
+---------+-------------+----------+------+------------+
| 1 | 201 | 101 | 2 | 2011-01-22 |
| 2 | 201 | 101 | 4 | 2011-01-27 |
| 3 | 202 | 106 | 4 | NULL |
| 4 | 203 | 103 | 2 | 2011-01-20 |
| 5 | 203 | 108 | 4 | 2011-01-12 |
| 6 | 203 | 108 | 2 | 2011-01-30 |
| 7 | 204 | 101 | 3 | 2011-01-09 |
| 8 | 205 | 103 | 3 | 2011-01-27 |
| 9 | 205 | 104 | 2 | 2011-01-22 |
| 10 | 205 | 108 | 4 | NULL |
| 11 | 206 | 107 | 3 | 2011-01-15 |
| 12 | 206 | 106 | 5 | 2011-01-19 |
| 13 | 207 | 107 | 5 | 2011-01-20 |
| 14 | 208 | 104 | 3 | 2011-01-02 |
+---------+-------------+----------+------+------------+
the rate is a set which has those values
('1','2','3','4','5'). i want to convert this set values to integers. i used cast(rate as unsigned) .then i used this query..
SELECT rate,cast(rate AS UNSIGNED) FROM rating;
it gives me this table
mysql> SELECT rate,cast(rate as unsigned) FROM rating;
+------+------------------------+
| rate | cast(rate as unsigned) |
+------+------------------------+
| 2 | 2 |
| 4 | 8 |
| 4 | 8 |
| 2 | 2 |
| 4 | 8 |
| 2 | 2 |
| 3 | 4 |
| 3 | 4 |
| 2 | 2 |
| 4 | 8 |
| 3 | 4 |
| 5 | 16 |
| 5 | 16 |
| 3 | 4 |
+------+------------------------+
it looks like binary values..plz help me to convert this into correct integer values..
Try this..
CAST (CAST(rate AS char) AS UNSIGNED);
it works..
ENUM is not a good selection for number values. instead of using ENUM you can use TYNYINT and filter values for only accept [1-5] in your code.
MYSQL document mention that clearly
We strongly recommend that you do not use numbers as enumeration values, because it does not save on storage over the appropriate TINYINT or SMALLINT type, and it is easy to mix up the strings and the underlying number values (which might not be the same) if you quote the ENUM values incorrectly. If you do use a number as an enumeration value, always enclose it in quotation marks. If the quotation marks are omitted, the number is regarded as an index. See Handling of Enumeration Literals to see how even a quoted number could be mistakenly used as a numeric index value.
Check this out : MYSQL DOC Enumeration Limitations
:)
You should try with this following ways.
The type for the result can be one of the following values:
BINARY[(N)]
CHAR[(N)]
DATE
DATETIME
DECIMAL[(M[,D])]
SIGNED [INTEGER]
TIME
UNSIGNED [INTEGER]
Thanks.