I have table person(id, iin, name, done) and table err_person(id, iin, surname, name). How i can find duplicate values within 'iin' fields. If it exist, copy to err_person table and set flag person.done=1 for these rows.
person table
desired results: err_person
To find duplicate values in a field:
SELECT iin
FROM person
GROUP BY iin
HAVING COUNT(*) > 1
You may wish to nest this query:
SELECT * FROM person WHERE iin IN (
SELECT iin
FROM person
GROUP BY iin
HAVING COUNT(*) > 1)
And so, to insert this into the err_person table you could do something like this (noting that the person table does not have a surname field):
INSERT INTO err_person (id, iin, name)
SELECT id, iin, name FROM person WHERE iin IN (
SELECT iin
FROM person
GROUP BY iin
HAVING COUNT(*) > 1)
Finally, a separate query would have to be run to change the done field. The problem with a nested query here is that you're updating a table that you're trying to look at, thus a simple effort to use an update query that looks at a subquery will fail - because both are based on the person table. A temporary table might be a better option here.
Related
I have this table structure for names_table:
Name
Age
Gender
Someone1
25
Male
Someone2
25
Female
Another table names_with_company has this structure:
CompanyID
Name
Age
Gender
Now, I want to copy the data from names_table by adding a single value to column of CompanyID.
Expected result:
CompanyID
Name
Age
Gender
1234
Someone1
25
Male
1234
Someone2
25
Female
I am quite confused what should I include.
INSERT INTO names_with_company
'1234',SELECT * FROM names_table
or
INSERT INTO names_with_company
SELECT * FROM (
'1234'
UNION
SELECT * FROM names_table
)
These two doesn't work
I know these two tables are two different structures, but is there any way to have a static value in column and rest of the data from another table?
Also, can you please not suggest creating another table and joining them? I prefer it to be done using the above code lines, but with a working logic.
Get into the habbit of always specifying the column names:
INSERT INTO names_with_company (CompanyID, Name, Age, Gender)
SELECT 1234, Name, Age, Gender
FROM names_table;
As you can see, you can provide "literal" values for any column.
you can not able to insert because your 1st query
INSERT INTO names_with_company
'1234',SELECT * FROM names_table
is completely wrong but if you written like below
INSERT INTO names_with_company
SELECT '1234',name,age,gender FROM names_table
it will work
but it is always better to mention the column name explicitly which is given in another answer by #stu
your 2nd query also wrong cause for union operation you have to provider same number of columns for all the selection
INSERT INTO names_with_company
SELECT * FROM (
'1234'
UNION
SELECT * FROM names_table
)
but you have used only one select
write method for union operation is like below
select col1,col2 from table1
union
select col1,col2 from table2
then you can use it any other way
Thank you for passing by. I know basic SQL syntax and I can't seem to find a way to accomplish this task.
I need to create a stored procedure which inserts data from one table in another, amid retrieving data from many others. Suppose I have these tables with columns:
users
name (varchar)
sub_id (int)
dub_id (int)
tmp_users
name (varchar)
sub_name (varchar)
dub_name (varchar)
subs
id (int)
name (varchar)
dubs
id (int)
name (varchar)
Translated in pseudocode I should do something like this:
INSERT INTO users (name, sub_id, dub_id)
ALL ROWS FROM tmp_users VALUES (
name = tmp_users.name,
sub_id = SELECT id FROM subs WHERE tmp_users.sub_name = subs.name,
dub_id = SELECT id FROM dubs WHERE tmp_users.dub_name = dubs.name,
)
In wording I need to insert into users all rows from tmp_users, to keep the col tmp_users.name, but retrieve the afferent ids of all other tables based on *_name column. How should I approach this task?
It seems like you are looking for the INSERT ... SELECT syntax:
INSERT INTO users (name, sub_id, dub_id)
SELECT
tu.name,
s.id,
d.id
FROM tmp_users tu
LEFT JOIN subs s ON s.name = tu.sub_name
LEFT JOIN dubs d ON d.name = tu.dub_name
This brings all rows from tmp_users, then attempt to recover the corresponding sub_id and dub_id. For each row returned by the select, a record is inserted in users. A good thing about this syntax is that you can run the select query independently first, to see what would be inserted.
I am trying to select a small number of records in a somewhat large database and run some queries on them.
I am incredibly new to programming so I am pretty well lost.
What I need to do is select all records where the Registraton# column equals a certain number, and then run the query on just those results.
I can put up what the db looks like and a more detailed explanation if needed, although I think it may be something simple that I am just missing.
Filtering records in a database is done with the WHERE clause.
Example, if you wanted to get all records from a Persons table, where the FirstName = 'David"
SELECT
FirstName,
LastName,
MiddleInitial,
BirthDate,
NumberOfChildren
FROM
Persons
WHERE
FirstName = 'David'
Your question indicates you've figured this much out, but are just missinbg the next piece.
If you need to query within the results of the above result set to only include people with more than two children, you'd just add to your WHERE clause using the AND keyword.
SELECT
FirstName,
LastName,
MiddleInitial,
BirthDate,
NumberOfChildren
FROM
Persons
WHERE
FirstName = 'David'
AND
NumberOfChildren > 3
Now, there ARE some situations where you really need to use a subquery. For example:
Assuming that each person has a PersonId and each person has a FatherId that corresponds to another person's PersonId...
PersonId FirstName LastName FatherId...
1 David Stratton 0
2 Matthew Stratton 1
Select FirstName,
LastName
FROM
Person
WHERE
FatherId IN (Select PersonId
From Person
WHERE FirstName = 'David')
Would return all of the children with a Father named David. (Using the sample data, Matthew would be returned.)
http://www.w3schools.com/sql/sql_where.asp
Would this be any use to you?
SELECT * from table_name WHERE Regestration# = number
I do not know what you have done up to now, but I imagine that you have a SQL query somewhere like
SELECT col1, col2, col3
FROM table
Append a where clause
SELECT col1, col2, col3
FROM table
WHERE "Registraton#" = number
See SO question SQL standard to escape column names?.
Try this:
SELECT *
FROM tableName
WHERE RegistrationNo = 'valueHere'
I am not certain about my solution. I would propose You to use view. You create view based on needed records. Then make needed queries and then you can delete the view.
View description: A view contains rows and columns, just like a real table. The fields in a view are fields from one or more real tables in the database.
Example:
CREATE VIEW view_name AS
SELECT column_name(s)
FROM table_name
WHERE condition
For more information: http://www.w3schools.com/sql/sql_view.asp
I want to create a table and populate it with records. the new table should be named majorlist and should include the student ID, the student name ( first and last names concatenated with a space in between), major and the age (In whole years) of each student. label the output columns SID, Name, Major, and Age.
create table majorlist
select studentid as 'SID' from students
select concat(firstname,' ',lastname) as "name" from students
select major as 'major' from students
select round((datediff(now(),DOB))/365) as "age" from students;
I know each one of these works separately but I cant figure out how to integrate them into a table without getting a error. I try removing the select statments from each one and still that doesnt work.
create table majorlist
select studentid as 'SID',
concat(firstname,' ',lastname) as "name",
round((datediff(now(),DOB))/365) as "age"
from students;
Yes the answer by #juergen d is good. You are creating the table by fetching a single table values students.
Then its better to use a single select statement for fetching. You can use the query like -
create table majorlist
select studentid as 'SID',
concat(firstname,' ',lastname) as 'name',round((datediff(now(),DOB))/365) as 'age'
from students;
I have a table with columns for ID, firstname, lastname, address, email and so on.
Is there any way to delete duplicate email addresses from the TABLE?
Additional information (from comments):
If there are two rows with the same email address one would have a normal firstname and lastname but the other would have 'Instant' in the firstname. Therefore I can distinguish between them. I just want to delete the one with first name 'instant'.
Note, some records where the firstname='Instant' will have just 1 email address. I don't want to delete just one unique email address, so I can't just delete everything where firstname='Instant'.
Please help me out.
DELETE n1 FROM customers n1, customers n2 WHERE n1.ID > n2.ID AND n1.email = n2.email
DELETE FROM table WHERE id NOT IN (SELECT MIN(id) FROM table GROUP BY email)
This keeps the lowest, first inserted id's for every email.
While MiPnamic's answer is essentially correct, it doesn't solve the problem of which record you keep and which you throw away (and how you sort out related records). The short answer is that this cannot be done programmatically.
Given a query like this:
SELECT email, MAX(ID), MAX(firstname), MAX(lastname), MAX(address)
FROM customers
makes it even worse - since you are potentially selecting a mixture of fields from the duplicate rows. You'd need to do something like:
SELECT csr2.*
FROM customers csr2
WHERE ID IN (
SELECT MAX(id)
FROM customers csr
GROUP BY email
);
To get a unique set of existing rows. Of course you still need to sort out all the lreated records (hint - that's the IDs ni customers table not returned by the query above).
I don't know if this will work in MYSQL (I haven't used it)... but you should be able to do something like the following snippets.
I'd suggest you run them in order to get a feel for if the right data is being selected. If it does work, then you probably want to create a constraint on the column.
Get all of the duplicate e-mail addresses:
SELECT
EMAILADDRESS, COUNT(1)
FROM
TABLE
GROUP BY EMAILADDRESS
HAVING COUNT(1) > 1
Then determine the ID from that gives:
SELECT
ID
FROM
TABLE
WHERE
EMAILADDRESS IN (
SELECT
EMAILADDRESS
FROM
TABLE
GROUP BY EMAILADDRESS
HAVING COUNT(1) > 1
)
Then finally, delete the rows, based on the above and other constraints:
DELETE
FROM
TABLE
WHERE
ID IN (
SELECT
ID
FROM
TABLE
WHERE
EMAILADDRESS IN (
SELECT
EMAILADDRESS
FROM
TABLE
GROUP BY EMAILADDRESS
HAVING COUNT(1) > 1
)
)
AND FIRSTNAME = 'Instant'
Duplicate the table structure
Put a Unique Key on the email of the new table (just for safe)
Do a INSERT on the new table SELECTING data from the older one GROUPING by the email address
Another way to dedeupe using forsvarir answer above but modifying it a bit. This way you can keep which ever record you choose to partition by:
BEGIN TRAN
DELETE
FROM [TABLE]
WHERE
ID IN (
SELECT a.ID
FROM
(
SELECT ROW_NUMBER() OVER(PARTITION BY Email ORDER BY Email) [RowNum], ID, Email
FROM [TABLE]
WHERE Email IN
(
SELECT
Email
FROM
[TABLE]
GROUP BY Email
HAVING COUNT(1) > 1
)
) a
WHERE a.RowNum > 1
)
--COMMIT TRAN
--ROLLBACK TRAN
You can follow this MySQL query:
DELETE p1
FROM Person p1, Person p2
WHERE p1.email = p2.email
AND p1.id> p2.id;