Creating a loop sequence and duplicating rows within one table - ms-access

I have a table containing:
Order Nr (Number)
Product (Short text)
Material (Short text)
Date (Date)
Amount (Number)
From (Number)
To (Number)
[From] and [To] repeat themselves with each [Order Nr]
How can I create in MS Access a new column containing a sequence using as boundaries values from columns [From] and [To]? (I tried concat, but it returns short text).
On top of that I would like to duplicate all of the values from other columns and paste them to the newly created rows accordingly. (That I guess would be a self-join, but I'm not sure how to proceed)
Values From and To which are my sequence boundaries have no pattern (meaning I never know how many [Products] will be in an [Order] and how will it be distributed).
into

You can join in a sequence table to get the desired results.
Personally, I use a sequence generating query based on MSysObjects, but others advocate just having a table with numbers.
First, create the sequence table/query, mine is named qSequence:
SELECT DISTINCT Abs(ones.ID Mod 10)+(Abs(tens.ID Mod 10)*10)+1 AS Sequence
FROM MSysObjects AS ones, MSysObjects AS tens;
This just generates a sequence of 1 to 100, I assume that meets your needs.
Then, we can just join in the sequence table:
SELECT MyTable.*, qSequence.Sequence
FROM MyTable, qSequence
WHERE qSequence.Sequence BETWEEN MyTable.From AND MyTable.To

Related

Generating an auto generated number with 6 digits

I am generating new ids for my animals and i am running the following Query
SELECT concat('TZ',YEAR(CURDATE()),FLOOR(RAND() * 999999.99)) as ID , animalid FROM adggeth.view_allanimals;
my output for the following query is
# ID, animalid
'TZ2019703169', 'TZN000044001722'
'TZ2019914906', 'TZN000067976797'
'TZ2019465022', 'TZN000094299429'
'TZ2019580395', 'TZN000192792688'
my expected output
# ID, animalid
'TZ2019000001', 'TZN000044001722'
'TZ2019000002', 'TZN000067976797'
'TZ2019000003', 'TZN000094299429'
'TZ2019000004', 'TZN000192792688'
How can generate a random number for my id to achieve the expected output
After changes i get the following unexpected error
using
CONCAT('TZ', YEAR(CURDATE()), LPAD(#seq, 6, '0'))
'TZ2019000001', 'TZN000044001722'
'TZ2019000001', 'TZN000067976797'
'TZ2019000001', 'TZN000094299429'
'TZ2019000001', 'TZN000192792688'
It looks like you want IDs with the format TZYYYYNNNNNN where YYYY is the present year and NNNNNN is a guaranteed sequential number. Here you ask about how to generate the sequential number in a way where it's guaranteed to be unique.
If you were using Oracle you could use a sequence object. But who can afford Oracle?
So, you need to simulate the sequence object in MySQL. It's a little nasty, but here we go:
Create the following table:
CREATE TABLE sequence (
sequence_id BIGINT NOT NULL AUTO_INCREMENT,
PRIMARY KEY (`sequence_id`)
)
Then, each time you need a new sequence number, issue these three queries one after the other:
INSERT INTO sequence () VALUES ();
DELETE FROM sequence WHERE sequence_id < LAST_INSERT_ID();
SET #seq := LAST_INSERT_ID();
The third line places a guaranteed unique number into the #seq variable. This guarantee holds even if you have dozens of different client programs connected to your database generating sequence numbers. (The DELETE query merely keeps this otherwise pointless table from taking up too much space.)
Once you have #seq you can use it to generate your id values, something like this.
CONCAT('TZ', YEAR(CURDATE()), LPAD(#seq, 6, '0'))
To reset the sequence number at the first of the next year simply drop and recreate the sequence table.

How to create random unique (not repeated) and fix length (9 digits) primary key in mysql database?

As the title, how to create a 9 digits number primary key which is random, unique, not repeated and from range 100000000 to 999999999?
And this method must be work on the godaddy server, seems godaddy have so many limitation.
I can only think of two reliable ways of creating unique numbers.
Use a systematic process, such as auto-incrementing, where you now the numbers are unique.
Store generated numbers in a table.
You want random numbers, so the first method could be applied using a pseudo-random number generator. But the second is probably simpler to implement.
It goes something like this:
create table numbers (
numberid int auto_increment primary key,
n varchar(10) not null unique
);
Then you need to create numbers using a loop. Do the following until it succeeds:
insert into numbers (n)
select cast((rand(*) * 900000000) + 1000000000 as varchar);
You can use last_inserted_id() to then get the most recent number inserted.
If pseudo-random is OK for you, you could create a trigger like this:
create trigger tr_setid before insert on mytable for each row
set new.id := (
select mod ((count(*) ^ 42) * 479001599 + 714320596, 900000000)+100000000
from mytable);
This system is not good if you also delete records from your table, as this solution assumes count(*) is one larger every time this trigger runs.
The multiplier is a prime and not a divisor of 900000000, guaranteeing that no duplicate number will be generated before all possible numbers have been visited.
The ^ operator is just mapping the count(*) so to make the generated series a bit less predictable.
With this trigger the first 10 records in the table will get these id values:
232387754
711389353
174384556
653386155
348394150
827395749
290390952
769392551
900374962
479376561

Can I create a mapping from interger values in a column to the text values they represent in sql?

I have a table full of traffic accident data with column headers such as 'Vehicle_Manoeuvre' which contains integers for example 13 represents the vehicle manoeuvre which caused the accident was 'overtaking moving vehicle'.
I know the mappings from integers to text as I have a (quite large) excel file with this data.
An example of what I want to know is percentage of the accidents involved this type of manoeuvre but I don't want to have to open the excel file and find the mappings of integers to text every time I write a query.
I could manually change the integers of all the columns (write query with all the possible mappings of each column, add them as new column, then delete the orginial columns) but this sould take a long time.
Is it possible to create some type of variable (like an array with first column as integers and second column with the mapped text) that SQL could use to understand how text relates to the integers allowing me to write a query below:
SELECT COUNT(Vehicle_Manoeuvre) FROM traffictable WHERE Vehicle_Manoeuvre='overtaking moving vehicle';
rather than:
SELECT COUNT(Vehicle_Manoeuvre) FROM traffictable WHERE Vehicle_Manoeuvre=13;
even though the data in the table is still in integer form?
You would do this with a Maneeuvres reference table:
create table Manoeuvres (
ManoeuvreId int primary key,
Name varchar(255) unique
);
insert into Manoeuvres(ManoeuvreId, Name)
values (13, 'Overtaking');
You might even have such a table already, if you know that 13 has a special meaning.
Then use a join:
SELECT COUNT(*)
FROM traffictable tt JOIN
Manoeuvres m
ON tt.Vehicle_Manoeuvre = m.ManoeuvreId
WHERE m.name = 'Overtaking';

update sql table current row

Complete noob alert! I need to store a largish set of data fields (480) for each of many devices i am measuring. Each field is a Decimal(8,5). First, is this an unreasonably large table? I have no experience really, so if it is unmanageable, I might start thinking of an alternative storage method.
Right now, I am creating a new row using INSERT, then trying to put the 480 data values in to the new row using UPDATE (in a loop). Currently each UPDATE is overwriting the entire column. How do I specify only to modify the last row? For example, with a table ("magnitude") having columns "id", "field1", "field2",...:
sql UPDATE magnitude SET field1 = 3.14; this modifies the entire "field1" column.
Was trying to do something like:
sql UPDATE magnitude SET field1 = 3.14 WHERE id = MAX(id)
Obviously I am a complete noob. Just trying to get this one thing working and move on... Did look around a lot but can't find a solution. Any help appreciated.
Instead of inserting a row and then updating it with values, you should insert an entire row, with populated values, at once, using the insert command.
I.e.
insert into tTable (column1, column2, ..., column n) values (datum1, datum2, ..., datum n)
Your table's definition should have the ID column with property identity, which means that it will autofill it for you when you insert, i.e. you don't need to specify it.
Re: appropriateness of the schema, I think 480 is a large number of columns. However, this is a straightforward enough example that you could try it and determine empirically if your system is able to give you the performance you need.
If I were doing this myself, I would go for a different solution that has many rows instead of many columns:
Create a table tDevice (ID int, Name nvarchar)
Create a table tData (ID int, Device_ID int, Value decimal(8,5))
-- With a foreign key on Device_ID back to tDevice.ID
Then, to populate:
Insert all your devices in tDevice
Insert one row into tData for every Device / Data combination
-- i.e. 480 x n rows, n being the number of devices
Then, you can query the data you want like so:
select * from tData join tDevice on tDevice.ID = tData.Device_ID

Most efficient code to set a sort order column / assign a sequential series of numbers to a column?

I've got a table that will hold a sequence of rows I want to be able to change the order in which I query and display them. So I've created a column called "sortorder" that is an integer. I'm looking for a quick SQL statement re-order these column values any time I make an adjustment (i.e. bump a column up, down, to top or bottom).
So, given a table like:
table xxx:
data varchar(x)
sortorder int(10)
..
When I want to parse rows I'll do something like this:
select * from xxx order by sortorder desc;
Would I propose doing is, setting the value of sortorder to be sequential in increments of 2, such as the first row sortorder=2, the second sortorder=4, etc.
Then if I arbitrarily want to move any row back one, I simply set sortorder=sortorder-1.
Then I run a routine to re-assign all the values of sortorder in increments of 2 (order by sortorder ASC) and reset all the numbers with the new row in its proper place.
I figure when I initially add a row to the table I will set the sortorder= max number of existing rows *2 + 2; What would be the best way to do this in SQL?
I'm looking for the most efficient statement to re-order the values of sortorder as such.
I'm also open to ideas on other ways you might maintain user-changeable sort order for an table of rows...
Thanks!