MySQL Create Table That Accept Check values That Starts With - mysql

I created a table for my cellphone contacts and I want to sort the cellphone numbers. Example if the phone number starts with 1 to 3 it belongs to the first telecommunications company and 4 to 6 belongs to other.
What I want to do is if the user enters their phone number the number will be inserted to the table of the telecom company but each telecom company is dependent on the ContactId which is the primary key in cellphoneContacts table.
I already tried using cellnum1 but nothing works
cellnum1 ENUM('1%','2%','3%') .............
cellnum1 VARCHAR(11) CHECK (cellnum1 IN ('1%','2%','3%')) .........
cellnum1 VARCHAR(11) CHECK (cellnum1 LIKE('1%','2%','3%'))

SELECT * FROM tbl_item WHERE SUBSTR([<Column name>], 1, X) = '<Your ID prefix>' ORDER BY [<Column name>]
Where X from SUBSTR is howmany characters do you want.
And please, be more specific with what you want in the future. :)

The MySQL Reference Manual says:
The CHECK clause is parsed but ignored by all storage engines.
Try a trigger...
If you are checking first character value , you can use substr on the NEW table rows to filter data :
substr(NEW.cellnum1 ,1,1) in ( 1,2,3)

Related

Auto increment in mysql by more than 1

I have an invoicing system that runs off an sql db.
Every time I create a new invoice, the invoice number increases by 1.
So invoice number 5000, the next is 5001, then 5002 and so on.
I want so that the next invoice number increased by a different number, Say 15.
So invoice number 5000, then 5015, then 5030 etc.
Is it possible to change something in phpmyadmin to achieve this.
TIA
Try this, do note that this is global, and not just one table. If you are going to just have this happen on one table, create an stored procedure to set the id instead of auto increment.
SET ##auto_increment_increment=2;
SET ##auto_increment_offset=2;
Documentation:
https://dev.mysql.com/doc/refman/8.0/en/replication-options-source.html#sysvar_auto_increment_increment
You can also just have a subquery decide what the invoice no is supposed to be and not have it autoincremented. I would suspect that this code should be written in the invoicing software itself (Which might not be possible, in your case, at which point my top example is the only way to go) but if you can edit the software, you simply need to select the highest invoice that exists, and then + 2 - then store that in the column you present.
You can do it with two columns. One ID with normal auto increment and one InvoiceNumber with a default value of (ID * 15):
ALTER TABLE `definitions`
ADD COLUMN `InvoiceNumber` INT NOT NULL DEFAULT (ID * 15) AFTER `DisplayOrder`;
I know that you can modify the step in mySQL, but it is a global change which would affect all tables. I suggest that you leave the data as is and use a view to multiply the values by 15.
Obviously you will replace the column description with a number of columns with the real information, date, customer etc. etc.
create table invoice_data(
id int primary key AUTO_INCREMENT,
description varchar(100)
);
create view invoices as
select
15 * id as invoice_number,
description
from invoice_data;
insert into invoice_data (description) values
('invoice 1 information'),('invoice 2 information');
select * from invoices;
invoice_number | description
-------------: | :--------------------
15 | invoice 1 information
30 | invoice 2 information
db<>fiddle here

mySql – How to search for available IDs

I have a mySQL table, which stores data of a user list and has an ID in unsigned tiny-int format (0 to 255 entries possible) as primary key. I enabled auto-increment in order to automatically set the key, which works fine so far.
When users log off I call ALTER TABLE sj_userlist AUTO_INCREMENT=1 which executes without errors.
However, the next logged in user still receives the ID+1 of the currently highest ID.
Example:
10 Users are online with the IDs 1,2,3,4,5,6,7,8,9,10
Users 1 and 2 to 9 log out - only ID 1 and 10 are still logged on
a new user logs in and receives ID 11 but I want him/her to get the 2
In case this behavior is correct, how can I achieve an alternative solution, which always starts at 1 incrementing untl the next available ID is found ?
Thanks in advance,
best
Alex
Possible solution.
Create a table for users registration. Define username column as unique.
Insert max amount of records into it according the datatype (0-255, for example).
When the user logs in and needs to register you use
UPDATE table
SET name = 'Current user name'
WHERE name IS NULL
ORDER BY id
LIMIT 1;
SELECT id
FROM table
WHERE name = 'Current user name';
This guarantee that user will get the least available number, and no interference/concurrence problems will occur.
When user log out then you use
UPDATE table
SET name = NULL
WHERE name = 'Current user name'
id is now free for re-use by the next user logged in.
If some problems occures on the client side, and user have not logged out correctly then his name will stay registered. But when he logged in the next time he will receive the same id - UPDATE will fail but SELECT will return non-freed id.
Nevertheless you must clear such old records periodically.

SQL Server 2008::How to use ALTER TABLE to add a new column that has unique number for every unique value in another column

To make it more clear, I have a table like this
Batch domain
---------------
14 xyz.com
14 abc.com
15 abc.com
15 xyz.com
I want a 3rd column that has unique number for every domain, doesn't matter which batch they are from.
Generally you would never do this by adding a column. What you need is to add a table for the domains that has an identity field called DomainID. Then the Batch domain table stores the ID not the domain name and it joins to the Domain table to get the names.
To answer your question, NEWID() and NEWSEQUENTIALID() can be used.
Note that as a function, Newid can be called via trigger/stored procedure/query but NEWSEQUENTIALID can only be set as the DEFAULT value for a column of type uniqueidentifier.
There are limitations on both, and SEQUENTIAL ID can be guessed or cause clusters if blackouts occur, but this can be managed if security is not a concern for the value.
ALTER TABLE [Schema_Name].[Table_Name]
ADD DomainID uniqueidentifier DEFAULT (NEWSEQUENTIALID() )
While it is dated, Dave Pinal has a good explanation between the two.

MySQL returns me results no matter what I type! :(

I have a user table that has an auto increment userid field that I would like to use as a login ID. The format of the userid field is 1,2,3,4,5,..etc.
However when I do a select statement like:
SELECT * FROM user WHERE userid='0001'
The above statement returns me the information for userid '1'. No matter how many '0' i put in front of the '1', I will always get the record for userid '1'
May I know how I might get it to return results only when it matches the exact userid (i.e., returns records for user with userid 1 when I type userid=1 and not userid=00000001)?
I'm sorry if I didn't explain this clearly enough. I'm trying to pick up SQL by doing online tutorials and it's so frustrating :(
If the ID is int please use this, also don't forget to wrap user with backticks as it's a reserved keyword:
SELECT * FROM `user` WHERE userid=0001;
or this:
SELECT * FROM `user` WHERE userid=1;
As you have mentioned you need EXACT ID record.
You are mixing up integer vs. string comparison. If your ID is INT, it is compared as integer (so the trailing zeros are omitted.)
If the user ID is an int, this is expected behaviour (00001 = 1).
Making the ID a varchar field will help. However, this doesn't sound like a great idea.
Why do you want to allow 000001 next to 001? It's bound to cause problems, with no discernible advantage (to me).
Either have an automatically incrementing ID (1 2 3 4 5 ....), or completely random strings generated when the user creates the record. The latter will make it impossible for people to guess other users' IDs which can be a good thing under certain circumstances.
This is because your auto-increment is of type INT (NUMBER), and you are looking for string comparision (in SQL varchar)
You should make your column type as VARCHAR and use this statement
select * from user where userid like '0001'
OR
select * from user where userid like '%0001%'
USE LIKE::
SELECT * FROM user WHERE userid LIKE '0001'
the datatype of the column userID is INT. When you create a statement and has condition on userID, mysql implicitly cast it into INT that's why the string 0001 is equivalent to 1.
Here's a suggestion you might want, change the data type of the userID into VARCHAR (string) and create an algorithm to increment the userID. When the column is string, 0001 is not equal to 1.

Unique constrain with condition MYSQL

I have User table in my DB.
A user has the fields name, company_id and status: boolean, 1- live, 0- deleted.
When a user is deleted, his status is set to 0.
The combination of a live user name in a company should be unique. After a user is deleted, I don't mind that a user should be created with the same name for the company.
My question is how do I define a uniuqe constrain for the fields name, company_id and status=1 (It's not a uniuqe constrain on those three field becuase I don't mind that the combination of name-company_id-0 will appear a few times in the table).
Thanks,
Dvora
Use NULL value for deleted users.
Unique key allows unlimited number of NULL values.
Update: Don't touch user name, NULL in status field is enough.
Which programming language you are using?
your logic shoule be as follows
select * from Table_name where name='' AND company_id = '' AND status = 1
if this return any rows give uniqueness error to the user else create it.
I would create another column to store a deleted user's previous name and set their real name to NULL when they're deleted (as well as setting the status to 0).
Then have a unique constraint on name and company. NULLs will not affect the uniqueness (since NULL != NULL) and you can still recover the user's original name if desired.
So the delete operation is something like:
update users
set prev_name = name,
name = null,
status = 0
where name = 'paxdiablo' and company = 'SmallGreen';
Would it be easier if you split "live" and "deleted" so they have their own tinyint/boolean columns ?
I would replace status field with deleted_at (datetime). When the user is active its value would be NULL, but when deleted, it would be set to current datetime.
Next, i would add unique index on username & deleted_at fields, which will allow me to delete more than one user with the same username (in at least 1 second interval).