I dont know if i choose the right title for my question.
I have that table like this in my database.
NAME class_num
-------------------------------------------------- --------
name1 2
name2 4
name3 1
And what I want to do is:
Update the class_num to be in order like the name. The result from what I want is that:
NAME class_num
-------------------------------------------------- ---------
name1 1
name2 2
name3 3
Is any way to do that with a QUERY?
Or I need to do from C# code?
Sorry my english, please help. Thanks.
In SQL Server, you can use an updatable CTE (or subquery):
with toupdate as (
select t.*, row_number() over (order by name) as new_class_num
from table t
)
update toupdate
set class_num = new_class_num;
Assuming:
that your ID field is not an IDENTITY field, and can be updated
That your Name column holds unique values (there are no duplicate names)
You can do something like this (example in T-SQL for SQL Server):
-- Select all Names in alphabetical order, and give them a row number
INSERT INTO #NewIdTable
SELECT ROW_NUMBER() OVER(ORDER BY name ASC) as Row, Name
FROM MyTable
-- Update the ID's using the RowNumber as a new ID.
UPDATE MyTable
SET Id = Row
FROM #NewIdTable INNER JOIN MyTable ON #NewIdTable.Name = MyTable.Name
Edit: Looks like you clarified in the comments that your class_num column is a key. Therefore you will have to adjust this method. Try updating "Name" by joining on the row-number instead, if your ID's are sequential. Alternately, you could drop the key constraint temporarily, update the ID's, and create the key again. Another method might be to simply create a new table with IDENTITY INSERT ON and copy the names over to it in alphabetical order.
Firstly You can delete your table that query
"TRUNCATE TABLE table_name"
And later, you can create your table again with that query
"CREATE TABLE table_name
(
column_name1 data_type(size),
column_name2 data_type(size),
column_name3 data_type(size),
....
);"
Related
My database is designed in SQL Server & I want get output in asp.net, LINQ, C#
I have 2 tables linked to 1 table (1:1)
My question is can I get a primary key linked to which table?
For example:
tbl_Document (ID, Date, ...)
tbl_Factor (ID, DocID, ...)
tbl_Finance (ID, DocID, ...)
What is the best way to know ID in tbl_Document linked to which table?
I can add record in tbl_Document as 'whichTable' and write the name of table in every column, and every time I want to search set "if" and check 'WhichTable'.
Is there a better way to do that?
Thanks, and sorry for my bad English :)
By default, you can get only all tables that have foreign key constraints to the parent table:
select object_name(f.referenced_object_id) pk_table, c1.name pk_column_name,
object_name(f.parent_object_id) fk_table, c2.name fk_column_name
from
sys.foreign_keys f
join sys.columns c1 on c1.object_id = f.referenced_object_id
join sys.columns c2 on c2.object_id = f.parent_object_id
join sys.foreign_key_columns k
on (k.constraint_object_id = f.object_id
and c2.column_id = k.parent_column_id
and c1.column_id = k.referenced_column_id )
where object_name(f.referenced_object_id) ='tbl_Document'
There is no such additional information regarding every particular row in parent table. It would be a duplicate information (since you can figure out it by searching in every child table). Thus, as you mentioned you can store child table name in the additional column and then as an option, construct sql dynamically to query child row.
i have two tables Table1 and Table2. Table1 have columns ID,stringIDs and Table2 Columns ID,data
i have created a trigger to delete rows based on table1.
it doesn't works if comma Seperated stringIDs
are more than one. it works if stringIDs is only single value
create trigger tgTriggerName after delete
on Table1
begin
delete from Table2 where ID in (old.stringIDs);
end
Gordon is right, this table structure is really probably not what you want. But if for some reason you must do it this way, this query might accomplish what you want:
delete from Table2
where ID = old.stringIDs -- ID matches exactly
or old.stringIDs like ID + ',%' -- Or ID is at beginning of list
or old.stringIDs like '%,' + ID -- Or ID is at end of list
or old.stringIDs like '%,' + ID + ',%' -- Or ID is in middle of list
But that's a mess. Don't do it. Instead remove the stringIDs column from Table1, and add a column to Table2 called Table1ID to indicate which Table1 ID this Table2 record belongs to. So Table2 would look like this
ID Table1ID Data
1 1 some data
2 1 some data
3 2 some data
4 2 some data
5 2 some data
...
Then your trigger query can simply be:
delete from Table2
where Table1ID = old.ID
Even more clean would be to skip the trigger completely and do a Foreign Key Contstraint with cascading delete. But I have a feeling that's a lesson for another day.
'stringIDs' from table1 save them in another table with foreign key reference than apply trigger on new table to delete records from table 2
I have 2 tables in firebird, one of the tables contains the duplicate ID's and the other one only the unique ones. So, I want to use a procedure to select the unique ID's from the duplicates table and insert those into the unique table. But, I don't really know how, can anyone help me?
EDIT: Here is an example:
There are 2 tables
## GASFLESSEN ##
ID CODE SUCCESS TARE_WEIGHT FILLING_NOZZLE //< Column "CODE" contains those unique ID's.
## READINGS ##
ID CODE_ID READING_TIME //< Column "CODE_ID" contains the duplicate ID's
Thanks guys.
If you want to get list of "unique" ID-s in the table where there is dublicates then use DISTINCT, ie
SELECT DISTINCT id FROM d
Now if you want to further restrict the resultset to records which have a id not yet in the "unique table" either join the tables or use NOT EXISTS ie
SELECT DISTINCT id FROM d WHERE NOT EXISTS(SELECT 1 FROM u WHERE u.id = d.id)
procedure CopyUniqueFromData;
declare var_id integer;
for
select distinct id from d into :var_id
do begin
insert into u (id) values (:var_id);
end
end
There are several ways to do this. In addition to the answer of ain this can also be done using MERGE:
MERGE INTO table_unique
USING (SELECT DISTINCT id FROM table_duplicates) src
ON table_unique.id = src.id
WHEN NOT MATCHED THEN
INSERT (id) values (src.id);
In my application, i want to show the newly added RECORDS by an import operation in a gridview. Is there is any method in sql to retrive newly added rows.
I tried to do it in using code and tried to get the difference before and after the insertion and its working perfectly but makes the application very slow. So, i want to do it in database itself.
Im using Mysql, ASP.NET.
Eg:
table may have these records before the import operation
ID Name
1 A
2 B
3 C
and after import the table may be like this.
ID Name
1 A
2 B
3 C
4 D
5 E
6 F
I want result like
ID Name
4 D
5 E
6 F
You need to have AUTO_INCREMENT column defined on table or alternatively you can use TIMESTAMP field to retrieve newly added records, try this:
SELECT *
FROM table_name
ORDER BY id DESC
LIMIT 10;
For single row insert you can use LAST_INSERT_ID after you INSERT query:
SELECT LAST_INSERT_ID();
For multi-row insert you can follow these steps:
START TRANSACTION;
SELECT MAX(id) INTO #var_max_id FROM table_name;
INSERT INTO table_name VALUES(..),(..),...;
SELECT MAX(id) INTO #var_max_id_new FROM table_name;
COMMIT;
SELECT *
FROM table_name
WHERE id BETWEEN (#var_max_id + 1) AND #var_max_id_new;
i think this will be more simple:
SELECT MAX(id) INTO #Max_table_Id FROM table;
// Insert operation here//////
SELECT * FROM table WHERE id>#Max_table_Id;
In case you use auto incremental IDs for your records, you can use:
SELECT * FROM [table] ORDER BY [id column] DESC LIMIT [number of records]
Otherwise you should add a TIMESTAMP colum to your records for this purpose and select by this column.
Personally, if there is an option, I wouldn't use the record IDs for this, as it is not what they are for. Record IDs can change throughout the lifetime of an application and they don't necessarily represent the order in which the items were added. Especially in data import/export scenarios. I'd prefer to create special columns to store such information, e.g. "CreatedAt", "ModifiedAt".
Is is possible to get new values for Id (IDENTITY) before inserting data in a table ?
Is is possible to write something like that :
INSERT INTO Table1
SELECT *GET_NEW_IDENTITY*, Field1, Field2 FROM Table2
I need the values of Id because I want to insert data in Table1 and, just after, insert data in another table which has a foreign key linked to Table1 (with Id)
IDENT_CURRENT. Returns the last identity value generated for a specified table or view. The last identity value generated can be for any session and any scope.
SCOPE_IDENTITY. Returns the last identity value inserted into an identity column in the same scope. A scope is a module: a stored procedure, trigger, function, or batch.
OUTPUT. Returns information from, or expressions based on, each row affected by an INSERT, UPDATE, DELETE, or MERGE statement. [...] The OUTPUT clause may be useful to retrieve the value of identity or computed columns after an INSERT or UPDATE operation.
you can also have the insert statement return the newly inserted value for later use. for example
create table demo( Id int identity primary key, data varchar(10))
go
insert into demo(data) output inserted.Id values('something')
No, because it is the act of adding a row which creates the new identity value.
To do what you want,
SELECT newid = ##identity FROM table
just after the INSERT
Why would you need to get the identity value before doing the insert? Just do the insert to Table2 returning SCOPE_IDENTITY() and then use the resulting Id value for your insert to Table1.
This is just fast demo. You can use new ID for insert for update, insert into another table, query, etc. in another way. Hoping I did not insert errors into script during formatting, editing post
-- run [1] before this script once to have environment
--create temporary table once if not dropped after
-- really only ID field is needed, the others are for illustration
create table #temp_id (Id int, d1 int, d2 int)
select * from Table2;-- this is read-only, filled once here source
select * from Table1;--interesting for following runs
insert into Table1
OUTPUT INSERTED.id
-- really only ID is needed, the rest is for illustration
, inserted.d1, inserted.d2 INTO #temp_id
select field1, field2, null-- null to be merged later
-- or inserted/updated into another table
from Table2;
select * from Table1;
select * from #temp_id;
MERGE Table1 AS TARGET
USING #temp_id AS SOURCE
ON (TARGET.id = SOURCE.id)
WHEN MATCHED
--AND OR are redundant if Table1.ID is PK
THEN
UPDATE SET TARGET.IDnew = SOURCE.id;
select * from Table1;
--drop table #temp_id
--drop table table1
--drop table table2
[1]
Reproducing the tables from question and filling with data
create table Table1( Id int identity primary key, d1 int, d2 int, IDnew int)
create table Table2( field1 int, field2 int)
insert into table2 values(111,222)
insert into table2 values(333,444)
IDENT_CURRENT('tableName') returns the current value of the identity for the given table. The identity value that will be assigned on Insert will be IDENT_CURRENT('tableName') + IDENT_INCR('tableName').
SELECT IDENT_CURRENT('tableName') + IDENT_INCR('tableName')