Here is a Sql-Server query, How do it in Postgresql? - sql

Here is a SQL-Server query, How do it in PostgreSQL?
DECLARE #p_key as int= NEXT VALUE FOR ProductSequence;
INSERT INTO Product(ID,Name,Price) VALUES(#p_key,#Name,#Price);
INSERT INTO ProductInfo(ID,Guid,DateCreation, DateLastChange, AgentCreationID,AgentLastChangeID) VALUES(#p_key, #Guid, #DateCreation, #DateLastChange, #AgentCreationID, #AgentLastChangeID);
SELECT #p_key;

Assuming product.id is defined as identity you can do that with a writeable CTE:
with new_product as (
insert into product (name, price)
values (...)
returning id
)
insert into product_info (id, guid, date_creation, date_last_change, anget_creation_id, agent_last_change_id )
select id, 'guid', ...
from new_product;
Otherwise just use nextval() and lastval()
insert into product
(id, name, price)
values
(nextvalue('product_id_seq'), ...);
insert into product_info
(id, guid, date_creation, date_last_change, anget_creation_id, agent_last_change_id )
values
(lastval(), ....);

Related

How to get the latest last 2 inserted records from the table

CREATE TABLE `testskm`(
`mem_id` NUMBER(5) NOT NULL,
`mem_sal` NUMBER(5) NOT NULL);
insert into `testskm` values (1,100);
insert into `testskm` values (1,200);
insert into `testskm` values (2,350);
insert into testskm values (2,150);
insert into testskm values (3,12);
insert into testskm values (1,300);
insert into testskm values (2,50);
insert into testskm values (3,13);
insert into testskm values (3,14);
insert into testskm values (3,15);
i have insert statements for mem_id 1,2, & 3. I want to get the last 2 inserted records in the table for all mem_id.
I have the tried the below code , but its giving me only records based on the mem_sal as i used the order by..
select * from(
select
mem_id, mem_sal,
--max(sysdate) over (partition by mem_id) latest,
rank() over( partition BY mem_id order by mem_sal ) RISK_ORDER
from testskm)
where RISK_ORDER <= 2
i want output of these inserted records:
insert into `testskm` values (1,200);
insert into `testskm` values (1,300);
insert into `testskm` values (2,150);
insert into `testskm` values (2,50);
insert into `testskm` values (3,14);
insert into `testskm` values (3,15);
SQL tables represent unordered sets. There is no "last two rows" unless a column specifies the ordering. Your table has no such column.
You can define one. In MySQL, this looks like:
create table `testskm` (
testskm_id int auto_increment primary key,
`mem_id` int NOT NULL,
`mem_sal` int NOT NULL
);
Then you can use row_number():
select ts.*
from (select ts.*, row_number() over (partition by mem_id order by testskm_id desc) as seqnum
from testskm ts
) ts
where seqnum <= 2;
Here is a db<>fiddle.

Referencing inserted ID in multiple insert transactions in Postgres

I need to build a SQL query that must be able to insert data in a first table, grab the inserted ID and then use it as foreign key in the following tables.
WITH inserted AS (
INSERT INTO firstTable (name) VALUES ('somename') RETURNING id
)
SELECT * FROM inserted; -- this has the inserted id
INSERT INTO secondTable (name, foreign_id) VALUES ('someexternalname', ???)
So how do I reference the id in inserted in the secondTable insert?
You have completed this 80% percent, the complete SQL is:
with inserted as (
insert into first_table(name) values ('somename') returning id
)
insert into second_table(name, foreign_id) select 'someexternalname',id from inserted
You can do this:
WITH inserted AS (
INSERT INTO firstTable (name) VALUES ('somename') RETURNING id
)
INSERT INTO secondTable (name, foreign_id)
SELECT
'someexternalname',
id
FROM inserted;
You can try this:
INSERT INTO secondTable (name, foreign_id) VALUES ('someexternalname', (SELECT
MAX (id) FROM firstTable))

Single SQLstatement for many INSERTs

Please see the DDL below:
CREATE TABLE #Test (ID INT NOT NULL IDENTITY, Name varchar(100), [Key] int, primary key (ID))
INSERT INTO #Test (Name, [Key]) values ('Ian',1)
INSERT INTO #Test (Name, [Key]) values ('Iain',1)
INSERT INTO #Test (Name, [Key]) values ('Eon',1)
INSERT INTO #Test (Name, [Key]) values ('Mark',2)
INSERT INTO #Test (Name, [Key]) values ('Steven',2)
and the DDL below:
CREATE TABLE #Test2 (ID INT NOT NULL IDENTITY, Name varchar(100), primary key (ID))
INSERT INTO #Test2 (Name) values ('Graham')
INSERT INTO #Test2 (Name) values ('William')
INSERT INTO #Test2 (Name) values ('Neil')
INSERT INTO #Test2 (Name) values ('Calum')
INSERT INTO #Test2 (Name) values ('Wayne')
I want to INSERT everything from #Test2 into #Test. I want each record in #Test2 to have a unique Key in #Test. In affect I want this to happen:
INSERT INTO #Test (Name, [Key]) VALUES ('Graham', 3)
INSERT INTO #Test (Name, [Key]) VALUES ('William', 4)
INSERT INTO #Test (Name, [Key]) VALUES ('Calum', 5)
INSERT INTO #Test (Name, [Key]) VALUES ('Wayne', 6)
There are millions of records in #Test and #Test2.
Is it possible to do all the INSERTS with a single SQL statement or do I have to use a cursor.
You need just new numbers that are higher than the max. key that exists? This should work:
declare #maxkey int
select #maxkey = max([Key]) from Test
insert into Test (Name, [Key])
select Name, row_number () over (order by (select null)) + #maxkey
from Test2
This just fetches the max. key and uses row_number to add numbers to the rows coming from Test2.
SQL Fiddle
You can try some logic like this:
insert into #Test
select Name, ((select max([Key]) from #Test) + ID) as [Key]
from #Test2
order by ID asc;
Here is my Fiddle example: Fiddle

MS SQL Server Last Inserted ID

In my database all tables are using a common table for Sequence(ID_Table).
TABLE_ID has two fields (Common_ID, Table_Name).
If I insert any record in the table, I have to first insert a record in Table_ID(Auto-increment, Table_name) then use that Auto-increment value in my Other Table.
For example, I want to insert in Table_Products which has fields ID(Common_ID), Product_Name, Product_ID(Auto Increment)
I want to do something like this:
INSERT INTO TABLE_ID (Table_NAME), Values (Table_Products)
Get the Inserted ID and use it in Table_Products:
INSERT INTO Table_Products (ID, Product_Name, Product_ID(Auto Increment)
VALUES (ID from TABLE_ID, SomeProduct, Increment)
Try this one -
DECLARE #ID BIGINT
INSERT INTO dbo.TABLE_ID (Table_NAME)
SELECT 'Table_Products'
SELECT #ID = SCOPE_IDENTITY()
INSERT INTO dbo.Table_Products (ID, Product_Name)
SELECT #ID, 'SomeProduct'
You can use an insert statement with the output clause to generate a new Common_ID. Using insert ... select, you can specify that ID in an insert operation:
declare #Common_ID as table(ID int)
insert Table_ID
(Table_Name)
output inserted.Common_ID into #Common_ID
values ('Table_Products')
insert Table_Products
(ID, Product_Name)
select ID
, 'Some Product'
from #Common_ID
Use SCOPE_IDENTITY() after ur insert statementto get the last inserted id.
DECLARE #Product_Id int
INSERT INTO TABLE_ID (Table_NAME) VALUES (Table_Products);
SELECT #Product_Id=SCOPE_IDENTITY();
Insert INTO Table_Products (ID, Product_Name)
VALUES (ID from TABLE_ID, 'SomeProduct')
Dear friend you have to select id of last record inserted
and then pass it in another table so bellow code will help you very well
Insert INTO TABLE_ID (Table_NAME), Values (Table_Products)
DECLARE #ID int;
set #ID = SCOPE_IDENTITY();
Insert INTO Table_Products (ID, Product_Name)
Values (#ID, SomeProduct)
this code will solve your problem i define #ID for your last record id and then insert it in your other table
For MySql use select LAST_INSERT_ID();
All the other answers so far declare intermediary variables for SCOPE_IDENTITY(), but it could be simpler:
INSERT INTO dbo.TABLE_ID (Table_NAME) VALUES 'Table_Products';
INSERT INTO dbo.Table_Products (ID, Product_Name) VALUES (SCOPE_IDENTITY(),'SomeProduct');
You could be also more table-specific using IDENT_CURRENT()
Insert INTO TABLE_ID (Table_NAME), Values (Table_Products)
select #NewID=IDENT_CURRENT('TABLE_ID')
Insert INTO Table_Products (ID, Product_Name, Product_ID
Values (#NewID, SomeProduct, Increment)

Querying a Many to Many Structure for a subset of joined rows

I have a simple many to many db structure:
Table 1: ITEM
Columns:
ITEM_ID, ITEM_NAME
Table 2: Attribute
Columns:
ATTRIBUTE_ID, ATTRIBUTE_NAME
Table 3: ITEM_ATTRIBUTE
ITEM_ID, ATTRIBUTE_ID
What I want is to "get all items that have the following x attributes". X can be any number of attributes.
The best I've come up with is the following, but I believe there has to be a better way using joins and/or "select where in" clauses...but I can't think of it.
SELECT * FROM Item
WHERE Item.ITEM_ID IN
(SELECT ITEM_ATTRIBUTE.item_ID FROM ITEM_ATTRIBUTE WHERE ITEM_ATTRIBUTE.attribute_ID =1)
and Item.ITEM_ID in
(SELECT ITEM_ATTRIBUTE.item_ID FROM ITEM_ATTRIBUTE WHERE ITEM_ATTRIBUTE.attribute_ID =3);
I'd rather not have to add an additional "ITEM_ID in (...) for each attribute in the list.. esp if the list of attributes is 20+ long
I would suggest populating a temporary table with the attributes that you would like to require. Once you have this table, the query becomes much cleaner and maintainable.
DECLARE #Item TABLE (
Item_Id INT,
Item_Name VARCHAR(50)
)
DECLARE #Attribute TABLE (
Attribute_Id INT,
Attribute_Name VARCHAR(50)
)
DECLARE #Item_Attribute TABLE (
Item_Id INT,
Attribute_Id INT
)
INSERT INTO #Item VALUES (1, 'Widget')
INSERT INTO #Item VALUES (2, 'Woozle')
INSERT INTO #Attribute VALUES (1, 'foo')
INSERT INTO #Attribute VALUES (2, 'bar')
INSERT INTO #Attribute VALUES (3, 'baz')
INSERT INTO #Attribute VALUES (4, 'qux')
INSERT INTO #Item_Attribute VALUES (1, 1)
INSERT INTO #Item_Attribute VALUES (1, 2)
INSERT INTO #Item_Attribute VALUES (1, 3)
INSERT INTO #Item_Attribute VALUES (2, 1)
INSERT INTO #Item_Attribute VALUES (2, 4)
DECLARE #Required_Attribute TABLE (
Attribute_Id INT
)
INSERT INTO #Required_Attribute VALUES (1)
INSERT INTO #Required_Attribute VALUES (2)
SELECT *
FROM #Item i
WHERE NOT EXISTS (
SELECT 1
FROM
#Required_Attribute ra
LEFT JOIN #Item_Attribute missingAttribute
ON ra.Attribute_Id = missingAttribute.Attribute_Id
AND missingAttribute.Item_Id = i.Item_Id
WHERE
missingAttribute.Attribute_Id IS NULL
)