I need to insert some data in a table named ‘queue’ which is a patient queue in a particular date . Two fields data will be inserted .Two fields name are ‘PatientID’ and ‘Visiting Date’. Table ‘queue' like
QueueID | PatientID | Visiting_date |
-------------|-------------------|-------------------------|
1 | 4 | Current date |
table:queue
But while inserting the record there are two conditions :
Condition 1 : patitentID comes from patient table (given below)
Condition 2 : one record will be inserted to ‘queue’ table if it does not exist to prevent repeatation.ie PatientID=4 will not be inserted if already inserted.
-------------|-----------------|------------------|
patitentID | Patient Name | Contact no |
-------------|-----------------|------------------|
4 | David | 01245785874 |
table:patient
My SQL is: (it does not work)
INSERT INTO `queue`(`patientID`, `Visiting_date`)
SELECT patient.`patientID`,’CURDATE()’ FROM `patient`
WHERE NOT EXISTS (
SELECT `patientID`, `visiting_date`FROM `queue`
WHERE `patientID` = '4' AND `visting_date`=CURDATE()
) LIMIT 1;
You could set a foreign key to make sure the patients id exists.
In the Queue table you can set patientID as unique, this makes sure you can insert only unique id's in the queue table.
Also if you would like to be able to insert the same userID but with different dates you could specify unique constraint for multiple columns in MySQL.
If you want to solve it with a mysql query only you can use this question.
I would use a separate query to check if there is a user with that ID in that table.
SELECT * FROM queue WHERE PatientID = 4;
and then check the result of that query, if it returns a row, that means that there is a user in there and you don't do anything.
If the query doesn't return a row, that means you can now use a query to inert a user. Like this
INSERT INTO queue (PatientID, VisitingDate);
Related
I am using Server version: 5.5.28-log MySQL Community Server (GPL).
I have a big table consist of 279703655 records called table A. I have to perform join on this table with one of my changelog table B and then insert matching records in new tmp table C.
B table has index on column type.
A table consist of prod_id,his_id and other columns.A table has index on both column prod_id,history_id.
When i am going to perform the following query
INSERT INTO C(prod,his_id,comm)
SELECT DISTINCT a.product_id,a.history_id,comm
FROM B as b INNER JOIN A as a ON a.his_id = b.his_id AND b.type="applications"
GROUP BY prod_id
ON DUPLICATE KEY UPDATE
`his_id` = VALUES(`his_id`);
it takes 7 to 8 min to insert records.
Even if i perform simple count from table A it took 15 min to give me count.
I have also tried a procedure to insert records in Limit but due to count query takes 15 min it is more slower then before.
BEGIN
DECLARE n INT DEFAULT 0;
DECLARE i INT DEFAULT 0;
SELECT COUNT(*) FROM A INTO n;
SET i=5000000;
WHILE i<n DO
INSERT INTO C(product_id,history_id,comments)
SELECT a.product_id,a.history_id,a.comments FROM B as b
INNER JOIN (SELECT * FROM A LIMIT i,1) as a ON a.history_id=b.history_id;
SET i = i + 5000000;
END WHILE;
End
But the above code is also take 15 to 20 min o execute.
Please suggest me how i make it faster.
Below is EXPLAIN result:
+----+-------------+-------+--------+---------------+---------+---------+-----------------+--------------+-------------+
| id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra |
+----+-------------+-------+--------+---------------+---------+---------+-----------------+--------------+-------------+
| 1 | SIMPLE | a | ALL | (NULL) | (NULL) | (NULL) | (NULL) | 279703655 | |
| 1 | SIMPLE | b | eq_ref | PRIMARY | PRIMARY | 8 | DB.a.history_id | 1 | Using index |
+----+-------------+-------+--------+---------------+---------+---------+-----------------+--------------+-------------+
(from Comment)
CREATE TABLE B (
history_id bigint(20) unsigned NOT NULL AUTO_INCREMENT,
history_hash char(32) CHARACTER SET utf8 COLLATE utf8_unicode_ci NOT NULL,
type enum('products','brands','partnames','mc_partnames','applications') NOT NULL,
stamp timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP,
PRIMARY KEY (history_id),
UNIQUE KEY history_hash (history_hash),
KEY type (type),
KEY stamp (stamp)
);
Let's first look at the tables.
What you call table B is really a history table. Its primary key is the history_id.
What you call table A is really a product table with one product per row and product_id its primary key. Each product also has a history_id. Thus you have created a 1:n relation. A product has one history row; one history row relates to multiple products.
You are selecting the product table rows that have an 'application' type history entry. This should be written as:
select product_id, history_id, comm
from product
where history_id in
(
select history_id
from history
where type = 'applications'
);
(A join would work just as well, but isn't as clear. As there is only one history row per product, you can't get duplicates. Both GROUP BY and DISTINCT are completely superfluous in your query and should be removed in order not to give the DBMS unecessary work to do. But as mentioned: better don't join at all. If you want rows from table A, select from table A. If you want to look up rows in table B, look them up in the WHERE clause, where all criteria belongs.)
Now, we would have to know how many rows may be affected. If only 1% of all history rows are 'applications', then an index should be used. Preferably
create index idx1 on history (type, history_id);
… which finds rows by type and gets their history_id right away.
If, say 20%, of all all history rows are 'applications', then reading the table sequentially might be more efficient.
Then, how many product rows may we get? Even with a single history row, we might get millions of related product rows. Or vice versa, with millions of history rows we might get no product row at all. Again, we can provide an index, which may or may not be used by the DBMS:
create index idx2 on product (history_id, product_id, comm);
This is about as fast as it gets. Two indexes offered and a proper written query without an unnecessary join. There were times when MySQL had performance problems with IN. People rewrote the clause with EXISTS then. I don't think this is still necessary.
As of MySQL 8.0.3, you can create histogram statistics for tables.
analyze history update histogram on type;
analyze product update histogram on history_id;
This is an important step to help the optimizer to find the optimal way to select the data.
Indexes needed (assuming it is history_id, not his_id):
B: INDEX(type, history_id) -- in this order. Note: "covering"
A: INDEX(history_id, product_id, comm)
What column or combination of columns provides the uniqueness constraint that IODKU needs?
Really-- Provide SHOW CREATE TABLE.
I have two tables in MySQL and I would like to update a column in one of them to match values from another.
The tables each have a customer and part number column.
Table 1:
Customer_Name | Part_Number | Demand | Allocation
Table 2:
Customer_Name | Part_Number | Demand
I want to update table 1 to add table 2 demand to the allocation figure in table 1, if the part number and customer both exist in table 2.
A query I have attempted so far:
UPDATE `Packing_Dispatch` SET Allocation = `Packing_Allocation`.Demand WHERE
Customer_Name = `Packing_Allocation`.Customer_Name AND Part_Number = `Packing_Allocation`.Part_Number
How can I do this?
You can try below
UPDATE `Packing_Dispatch`
Join `Packing_Allocation`
SET Allocation = `Packing_Allocation`.Demand
WHERE Customer_Name = `Packing_Allocation`.Customer_Name AND Part_Number = `Packing_Allocation`.Part_Number
I've inserted unique records from one table to another table this way:
insert into unidata
select distinct SourceFrom,Updated,Location_Type,First_Name,Middle_Name,
Last_Name,Designation,Company_Name,Address1,Address2,Address3,City,Pincode,STD_code,Extn,Fax_No,Office_Mobile_No,Website,Email_Office,Email_Personal1,Email_Personal2,
Residence_Address1,Residence_Address2,Residence_Address3,Residence_City,Residence_Pincode,Residence_STD_Code,
Residence_Phone_No,Personal_Mobile1,Personal_Mobile_NDNC,Work_Experience,Key_Skills,Personal_Mobile2,
State
from mytable src
where not exists(select *
from unidata dest
where (src.SourceFrom=dest.SourceFrom and src.Updated=dest.Updated and src.Location_Type=dest.Location_Type
and src.Industry=dest.Industry and src.First_Name=dest.First_Name and
src.Middle_Name=dest.Middle_Name and src.Last_Name=dest.Last_Name and src.Designation=dest.Designation and
src.Company_Name=dest.Company_Name and src.Address1=dest.Address1 and src.Address2=dest.Address2 and
src.Address3=dest.Address3 and src.City=dest.City and src.Pincode=dest.Pincode and src.STD_code=dest.STD_code and
src.Office_Mobile_No=dest.Office_Mobile_No and
src.Website=dest.Website and src.Email_Office=dest.Email_Office and src.Email_Personal1=dest.Email_Personal1 and
src.Email_Personal2=dest.Email_Personal2 and src.Residence_Address1=dest.Residence_Address1 and
src.Residence_Address2=dest.Residence_Address2 and src.Residence_Address3=dest.Residence_Address3 and
src.Residence_City=dest.Residence_City and src.Residence_Pincode=dest.Residence_Pincode and
src.Residence_STD_Code=dest.Residence_STD_Code and src.Residence_Phone_No=dest.Residence_Phone_No and
src.Personal_Mobile1=dest.Personal_Mobile1 and src.Personal_Mobile_NDNC=dest.Personal_Mobile_NDNC and
src.Work_Experience=dest.Work_Experience and src.Key_Skills=dest.Key_Skills and
src.Personal_Mobile2=dest.Personal_Mobile2 and src.State=dest.State)
)
This way it inserted records which were having exactly same duplicates like rows with exactly same filled columns. But there are records which are duplicates but with less or more records.
Email_Personal1 | Email_P2 |key_skills | state
abc#yahoo.com null null null
abc#yahoo.com null DBA null
Above is the example, I showed up with only few columns. It applies to all the columns. Like few columns are having the same record in that row and its duplicate rows have few more columns with new values which I can't remove using above query.It takes such thing as unique records. I want to update the record with all the available columns from its duplicate rows and after that delete the removing duplicates rows. I want this way:
Email_Personal1 | Email_P2 |key_skills | state
abc#yahoo.com null DBA null
Just store it as one final unique record rather than keeping two records as unique. Can anyone guide me here?
Updated (For Output):
I have a set of records that I want to add a unique index to, however some existing records conflict with that index, so I want to identify them and remove them in order that the constraint can be placed on the data.
Is there a way I can write a SELECT query based around any record that contradicts the unique index?
Example:
Table has columns
id | user | question_id | response | is_current
I want a unique index such that
user | question_id | response |is_current
is not duplicated.
Is it possible to SELECT all records where that set of values is not unique?
Show non-unique:
select user,question_id,response,is_current,count(*) as theCount
from tablename
group by user,question_id,response,is_current
having theCount>1
I have a table like this
id | name | zip
1 | abc | 1234
2 | xyz | 4321
3 | asd | 1234
I want to insert records such that the id and name when inserted may have the same value but if the value of zip is also same for that particular record it is not inserted. If not it should be inserted.
eg: I can insert another row with value for id=1 and value for name= abc but if that record also has zip=1234 it should not be inserted.
How can I achieve this.
Create two unique indexes:
create unique index idx_table_name_zip on table(name, zip)
create unique index idx_table_id_zip on table(id, zip)
The database will then guarantee the uniqueness you want to enforce.
Make a Primary Key from id, name and zip combined
ALTER TABLE table ADD PRIMARY KEY(id, name, zip)
With this a row/record is marked duplicate if all the three columns are same otherwise it is a perfectly fine non-duplicate record.
check this for more here
you need to make a check before inserting the row, for exmpale
select * from table where zip = #zip and name = #name and id = #id
if no rows return you can do the insert...