CONCAT and how to write syntax mysql - concatenation

I need to create a table for usernames. I need to get my info from a table person. I have to use the concat function to do this.
Im having trouble with the syntax needed.I tried
INSERT INTO users (volunteer_id, username) select concat ('Ronald', 'McDonald');
and many others. HELP am i even close.

Something like this :
Insert into users(volunteer_id, username) values(volunteeridvalue, (select concat('ronald','mcdonald'));
Volunteeridvalue being whatever you are inserting in there for that

create
create table if not exists users (
volunteer_id tinyint(3) unsigned not null auto_increment primary key,
username char(30)
)
insert all rows
insert into users (username) select concat (first_name,' ', last_name) from person
insert rows with exact value
insert into users (username) select concat (first_name,' ', last_name) from
person where first_name = 'Ronald'
person - existing table source of values to insert
first_name, last_name - columns in table person
users - new table to which values will be inserted
(if they have other names change it in query)

Related

Calling Identity column without inserting any data from source

I have a table with Identity column set on ID
Ex:
Create table Customer
(
ID Int identity (1,1),
FirstName varchar(20),
PhNumber int,
)
I have a table on other database which populates this table
So I wrote something like
Create or alter view abcCustomer
As
Select
? as ID
Fname as FirstName,
Pnumber as phnumber
From dbo.Scustomer (this is my table in source)
Here we are creating ID column in target only but not sure how to call or what to call from source so that it doesn’t affect the AbcCustomer View and populate identity records in target table and also the FirstName and phNumber from the source table.
Could anyone help what should I write in place of ? In order to get my table populated as identity column, because unless and until we call the ID column from the source it’s gonna end up with having errors.
there are so many ways to get id and others data from source table!
Using Where condition (you can use stored procedure):
Declare #i as int = 1
Select Id, FName, PhNumber From dbo.SCustomer Where Id = #i
set #i = #i+1
Using Offset:
Declare #i as int = 1
Select Id, FName, PhNumber from Dbo.Sccustomer Order By Id Offset #i Rows Fetch
Next #i Rows Only
Set #i = #i+1
If you want to insert data from the source customer table to target customer table then you should write a query in this way -
Option 1 - If you want to use the identity same as in the source table then Turn on the identity so that you will be able to insert value in the identify column (refer below query)
SET IDENTITY_INSERT Customer ON
Insert Customer
(ID, FirstName, PhNumber)
Select
ID as ID
Fname as FirstName,
Pnumber as phnumber
From dbo.Scustomer
SET IDENTITY_INSERT Employee OFF
Option 2 - If you want to generate the new identity in the source table then use the below query.
Insert Customer
(FirstName, PhNumber)
Select
Fname as FirstName,
Pnumber as phnumber
From dbo.Scustomer

Can I grab the inserted IDs when doing multiple inserts?

In my head this sounds improbable, but I'd like to know if I can do it:
INSERT INTO MyTable (Name)
VALUES ('First'),
('Second'),
('Third'),
('Fourth'),
('Fifth');
SELECT INSERTED Name, ID FROM TheAboveQuery
Where ID is an auto-indexed column?
Just to clarify, I want to select ONLY the newly inserted rows.
Starting with SQL Server 2008 you can use OUTPUT clause with INSERT statement
DECLARE #T TABLE (ID INT, Name NVARCHAR(100))
INSERT INTO MyTable (Name)
OUTPUT INSERTED.ID, INSERTED.Name INTO #T
VALUES
('First'),
('Second'),
('Third'),
('Fourth'),
('Fifth');
SELECT Name, ID FROM #T;
UPDATE: if table have no triggers
INSERT INTO MyTable (Name)
OUTPUT INSERTED.ID, INSERTED.Name
VALUES
('First'),
('Second'),
('Third'),
('Fourth'),
('Fifth');
Sure, you can use an IDENTITY property on your ID field, and create the CLUSTERED INDEX on it
ONLINE DEMO
create table MyTable ( ID int identity(1,1),
[Name] varchar(64),
constraint [PK_MyTable] primary key clustered (ID asc) on [Primary]
)
--suppose this data already existed...
INSERT INTO MyTable (Name)
VALUES
('First'),
('Second'),
('Third'),
('Fourth'),
('Fifth');
--now we insert some more... and then only return these rows
INSERT INTO MyTable (Name)
VALUES
('Sixth'),
('Seventh')
select top (##ROWCOUNT)
ID,
Name
from MyTable
order by ID desc
##ROWCOUNT returns the number of rows affected by the last statement executed. You can always see this in the messages tab of SQL Server Management Studio. Thus, we are getting the number of rows inserted and combining it with TOP which limits the rows returned in a query to the specified number of rows (or percentage if you use [PERCENT]). It is important that you use ORDER BY when using TOP otherwise your results aren't guaranteed to be the same
From my previous edited answer...
If you are trying to see what values were inserted, then I assume you are inserting them a different way and this is usually handled with an OUTPUT clause, TRIGGER if you are trying to do something with these records after the insert, etc... more information would be needed.

Retrieve original and new identities mapping from SELECT INSERT statement using OUTPUT clause

I have a table with two columns:
CREATE TABLE MyTable(
Id int IDENTITY(1,1) NOT NULL,
Name nvarchar(100) NOT NULL);
I want to duplicate the data using SELECT INSERT statement:
INSERT INTO MyTable (Name)
SELECT Name FROM MyTable
and here is the trickey part - I want to retrieve a mapping table between the original identity and the new identity:
DECLARE #idsMap TABLE (OriginalId int, NewId int)
I know I suppose to use the OUTPUT clause, but for some reason it doesn't work:
INSERT INTO MyTable (Name)
OUTPUT t.Id, INSERTED.Id INTO #idsMap (OriginalId, NewId)
SELECT Name FROM MyTable t
-- Returns error The multi-part identifier "t.Id" could not be bound.
Related questions:
can SQL insert using select return multiple identities?
Possible to insert with a Table Parameter, and also retrieve identity values?
It can be achieved using MERGE INTO and OUTPUT:
MERGE INTO MyTable AS tgt
USING MyTable AS src ON 1=0 --Never match
WHEN NOT MATCHED THEN
INSERT (Name)
VALUES (src.Name)
OUTPUT
src.Id,
inserted.Id
INTO #idsMap;
How about just adding a new column to MyTable? You can keep it around as long as you need to analysis or whatever. I have to say it seems a bit off to me to create a copy of the table but that is up to you to decide.
Something like this might work for you.
alter table MyTable
add OldID int null;
INSERT INTO MyTable (Name, OldID)
SELECT Name , Id
FROM MyTable t
select * from MyTable

How can I insert into two tables in different SQL Server 2008 databases

Example from pic.
http://pic.free.in.th/id/d56133ad2238308e979aa3dbea94436e
i want to insert data into Database A table A and Database B Table B in same time but some column from table A to Table B
EX.
table A have column ID,Name,Address,tel.I want just insert data ID,Name into table B.
(insert data to table B automaticly when insert data to table A )
if you have any idea please let me know.
You can do an insert with a SELECT.
INSERT INTO DataBaseB.dbo.TableB (ID, Name)
SELECT ID, Name from DatabaseA.dbo.TableA
See here for more details:
http://www.w3schools.com/sql/sql_insert_into_select.asp
This assumes both databases are on the same server, if not, you could always export/import the data?
ALTER TRIGGER [dbo].[ticky2]
ON [dbo].[data]
AFTER INSERT
AS
INSERT INTO [testDatabase].[dbo].[pool]
([ID]
,[Name]
,[salary]
,[date])
SELECT ID, Name,salary,date from deconc.dbo.data
where ID not in
(
select ID
from [testDatabase].[dbo].[pool]
)

Most efficient design to search for this data in my database?

I have the following database tables and a view which represents that data. The tables are heirachial (if that is how u describe it) :-
EDIT: I've replace my 3 tables with
FAKE table names/data (for this post)
because I'm under NDA to not post
anything about out projects, etc. So
yeah.. I don't really save people
names like this :)
FirstNames
FirstNameId INT PK NOT NULL IDENTITY
Name VARCHAR(100)
MiddleNames
MiddleNameId INT PK NOT NULL IDENTITY
Name VARCHAR(100) NOT NULL
FirstNameId INT FK NOT NULL
Surnames
SurnameId INT PK NOT NULL IDENTITY
Name VARCHAR(100) NOT NULL
FirstNameId INT FK NOT NULL
So, the firstname is the parent table with the other two tables being children.
The view looks like...
PersonNames
FirstNameId
FirstName
MiddleNameId
MiddleName
SurnameId
Surname
Here's some sample data.
FNID FN MNID MN SNID SN
-----------------------------------
1 Joe 1 BlahBlah 1 Blogs
2 Jane - - 1 Blogs
3 Jon - - 2 Skeet
Now here's the problem. How can i efficiently search for names on the view? I was going to have a Full Text Search/Catalogue, but I can't put that on a view (or at least I can't get it working using the GUI against a View).
EDIT #2: Here are some sample search queries :-
exec uspSearchForPeople 'joe blogs' (1 result)
exec uspSearchForPeople 'joe' (1 result)
exec uspSearchForPeople 'blogs' (2 results)
exec uspSearchForPeople 'jon skeet' (1 result)
exec uspSearchForPeople 'skeet' (1 result)
Should i generate a new table with the full names? how would that look?
please help!
This doesn't seem like the most logical design decision. Why did you design it like this?
What's your indexing structure currently? A index on Name on each of the 3 tables should speed up the query?
Alternatively, normalizing further and creating a Name table and having NameID in each of the three, then indexing the Name table should also increase performance, but I think indexing the name field on the 3 tables would be easier and work as well.
What's the stats on updates vs selects, as adding these indexes might incur a performance hit.
crazy design, possibly the fake table names makes it stranger than it is.
create indexes based on select usage.
if you are searching on actual first names like "Joe" you need an index on FirstNames.Name
if you are searching on first name ids like 123, you have an index: FirstNames.FirstNameId
if you want to search on FirstNames.name and/or MiddleNames.name and/or Surnames.name you need to have indexes on the combinations that you will use, and the more you make, the harder for the query to pick the best one.
ditch the view and write a dedicated query for the purpose:
go after first/middle
select
FirstNames.name
,MiddleNames.name
,Surnames.name
FROM FirstNames
INNER JOIN MiddleNames ON FirstNames.FirstNameId=MiddleNames.FirstNameId
INNER JOIN Surnames ON FirstNames.FirstNameId=Surnames.FirstNameId
WHERE FirstNames.Name='John'
AND MiddleNames.Name='Q'
go after last
select
FirstNames.name
,MiddleNames.name
,Surnames.name
FROM Surnames
INNER JOIN FirstNames ON Surnames.FirstNameId =FirstNames.FirstNameId
INNER JOIN MiddleNames ON FirstNames.FirstNameId=MiddleNames.FirstNameId
WHERE Surnames.Name='Public'
just make sure you have indexes to cover your main table in the "where" clause
use SET SHOWPLAN_ALL ON to make sure you are using an index ("scans" are bad "seeks" are good")
EDIT
if possible break the names apart before searching for them:
exec uspSearchForPeople 'joe',null,'blogs' (1 result)
exec uspSearchForPeople 'joe',null,null (1 result)
exec uspSearchForPeople null,null,'blogs' (2 results)
exec uspSearchForPeople 'jon',null,'skeet' (1 result)
exec uspSearchForPeople null,null,'skeet' (1 result)
within the stored procedure, have three queries:
if #GivenFirstName is not null
--search from FirstNames where FirstNames.name=#value & join in other tables
else if #GivenMiddleName is not null
--search from MiddleNames where MiddleNames.name=#value & join in other tables
else if #GivenLastName is not null
--search from Surnames where Surnames.name=#value & join in other tables
else --error no names given
have an index on all three tables for Names.
if you can not split the names apart, I think you are out of luck and you will have to table scan every row in each table.
Just think of a phone book if you don't use the index and you are looking for a name, you will need to read the entire book
I would have just one table with a name type column (first, middle, last) and an FK onto itself with the clustered index on the name column.
CREATE TABLE [Name] (
NameID INT NOT NULL IDENTITY,
[Name] varchar(100) not null,
NameType varchar(1) not null,
FirstNameID int null,
)
ALTER TABLE [Name] ADD CONSTRAINT PK_Name PRIMARY KEY NONCLUSTERED (NameID)
ALTER TABLE [Name] ADD CONSTRAINT FK_Name_FirstNameID FOREIGN KEY (FirstNameID) REFERENCES [Name](NameID)
CREATE CLUSTERED INDEX IC_Name ON [Name] ([Name], NameType)
DECLARE #fid int
INSERT [Name] ([Name], NameType, FirstNameID) VALUES ('Joe', 'F', NULL)
SELECT #fid = scope_identity()
INSERT [Name] ([Name], NameType, FirstNameID) VALUES ('BlahBlah', 'M', #fid)
INSERT [Name] ([Name], NameType, FirstNameID) VALUES ('Blogs', 'L', #fid)
INSERT [Name] ([Name], NameType, FirstNameID) VALUES ('Jane', 'F', NULL)
SELECT #fid = scope_identity()
INSERT [Name] ([Name], NameType, FirstNameID) VALUES ('Blogs', 'L', #fid)
INSERT [Name] ([Name], NameType, FirstNameID) VALUES ('Jon', 'F', NULL)
SELECT #fid = scope_identity()
INSERT [Name] ([Name], NameType, FirstNameID) VALUES ('Skeet', 'L', #fid)
You could then build a dynamic but paramterized WHERE clause based on the number of values to search (or hard-code them for that matter assuming there are only at most 3) using sp_executsql in a stored proc, linq to sql, or even ugly string manipulation in code.
I think what you are wanting is an Index table. It doesn't matter how many tables and columns you have in those tables as stuff is inserted into the database it gets indexed. ex.
I would recommend one table for your names.
NameTable
----------
Id
FirstName
MiddleName
LastName
You can have as many normal tables as you want...
IndexTable
----------
Id
Text
You could use the text as the primary key but I always have a separate id column for the primary key (just habit).
IndexItemTable
----------
Id
IndexId // Has a foreign key reference to IndexTable Id
ReferenceId // The record Id of where the text occures
ReferenceTable // The table where the text occures
Then as you insert a name "Jim Barbarovich Fleming" you would also scan you index and find that its empty and create 3 new records for Jim, Barbarovic, and Fleming that would all have the same referenceId and the ReferenceTable would be "NameTable" then you insert another record like "Jim Bradley Fleming" you would scan the index table and see that you already have values for "Jim" and "Fleming" so you would just create IndexItem with referenceId of 2 and ReferenceTable of "NameTable".
By building and index you can search via a single textbox and find all records/fields in your database that have those values.
Note: you going to want to change everything when you insert it to the index to uppercase or lower case and then use equals(value, OrdinalIgnoreCase).
Edit:
I can't just upload the image. I have to host it somewhere I guess but It not any different than the table diagrams I put above. The only relationship IndexTable has is to IndexItemTable. I would do the rest in code. ex.
During Insert or Update of new record in Name table you would have to:
Scan IndexTable and see if each of the fields in the NameTable exist.
If they don't you would add a new record to the Index table with the text that wasn't found. If they do the go on to step 3.
Add a record in the IndexItemTable with the referenceId (the id of the record in the NameTable) and ReferenceTable (NameTable) and then the IndexId of the text found in the IndexTable.
Then when they do a search via your single text box you search for each word in the index table and return the Names from the NameTable that are referenced in the IndexTable.

Resources