How to add results of a SELECT to a table - sql

I have a SQL select statement which is comparing two tables. I am getting the values where the rows are the same. Now I have got this in the procedure I need to add these into a new table (coftReconciliationMatches). The table has all the same columns but one additional one 'MatchOrNoMatch'. I need to pass through the values of the row that are matched and also need to pass through 'Match' to the column 'MatchOrNoMatch'
This is the current part of the SQL script I have;
SELECT *
FROM dbo.coftReconciliationFileInfo AS a
WHERE EXISTS (SELECT *
FROM dbo.coftPreReconciliationInfo AS b
WHERE a.Rec_PK = b.Rec_PK
AND a.ExtRef1 = b.ExtRef1
AND a.SedolRef = b.SedolRef
AND a.ValLatest = b.ValLatest
AND a.Totunits = b.Totunits
AND a.FundsOrCash = b.FundsOrCash )

When comparing a lot of columns, the SELECT INTERSECT and SELECT EXCEPT commands can save you a lot of effort:
INSERT dbo.coftReconcilliationMatches
(Rec_PK, ExtRef1, SedolRef, ValLatest, Totunits, FundsOrCash, MatchOrNoMatch)
select Rec_PK, ExtRef1, SedolRef, ValLatest, Totunits, FundsOrCash, 'Match'
from dbo.coftReconciliationFileInfo
intersect select Rec_PK, ExtRef1, SedolRef, ValLatest, Totunits, FundsOrCash, 'Match'
from dbo.coftPreReconciliationFileInfo
(Check for typos!)
If you are creating the table on the fly (something I wouldn't recommend doing), you'd use SELECT INTO.

INSERT INTO [table] ([col1], [col2]) SELECT colx, ...

Use Select Into for this. See here http://www.w3schools.com/sql/sql_select_into.asp

Try something like:
INSERT INTO <your table> (<list of columns>)
SELECT <list of columns from select>, '<the additional column>' FROM dbo.coftReconciliationFileInfo AS a
WHERE EXISTS(SELECT * FROM dbo.coftPreReconciliationInfo AS b
WHERE a.Rec_PK = b.Rec_PK AND a.ExtRef1 = b.ExtRef1 AND a.SedolRef = b.SedolRef AND a.ValLatest = b.ValLatest AND a.Totunits = b.Totunits AND a.FundsOrCash = b.FundsOrCash )
also see http://www.1keydata.com/sql/sqlinsert.html

you need to do:
INSERT INTO Table (column1, column2..)
(SELECT column1, column2 ....
FROM dbo.coftReconciliationFileInfo AS a
WHERE EXISTS (SELECT *
FROM dbo.coftPreReconciliationInfo AS b
WHERE a.Rec_PK = b.Rec_PK
AND a.ExtRef1 = b.ExtRef1
AND a.SedolRef = b.SedolRef
AND a.ValLatest = b.ValLatest
AND a.Totunits = b.Totunits
AND a.FundsOrCash = b.FundsOrCash ))

Related

How do I UPDATE from a SELECT in Informix?

I'm trying to do an update using data from another table. I've tried this answer (the second part), but it is not working for me. I'm receiving a generic error message of syntax error.
I've also tried this solution and received a syntax error message too.
If I try to update just one column, it works:
UPDATE dogs
SET name =
(
SELECT 'Buddy'
FROM systables
WHERE tabid = 1
);
But I need to update multiples columns. Unfortunately, this is not working:
UPDATE dogs
SET (name, breed) =
(
SELECT 'Buddy', 'pug'
FROM systables
WHERE tabid = 1
);
Informix version is 12.10.FC8
You are missing 1 more set of parentheses around the subquery.
From the Informix manual:
The subquery must be enclosed between parentheses. These parentheses
are nested within the parentheses that immediately follow the equal (
= ) sign. If the expression list includes multiple subqueries, each subquery must be enclosed between parentheses, with a comma ( , )
separating successive subqueries:
UPDATE ... SET ... = ((subqueryA),(subqueryB), ... (subqueryN))
The following examples show the use of subqueries in the SET clause:
UPDATE items
SET (stock_num, manu_code, quantity) =
(
(
SELECT stock_num, manu_code
FROM stock
WHERE description = 'baseball'
),
2
)
WHERE item_num = 1 AND order_num = 1001;
UPDATE table1
SET (col1, col2, col3) =
(
(
SELECT MIN (ship_charge), MAX (ship_charge)
FROM orders
),
'07/01/2007'
)
WHERE col4 = 1001;
So in order for your update to be accepted by Informix it has to be:
UPDATE dogs
SET (name, breed) =
(
(
SELECT 'Buddy', 'pug'
FROM systables
WHERE tabid = 1
)
);

Two or more results of one CASE statement in SQL

Is it possible to SELECT value of two or more columns with one shot of CASE statement? I mean instead of:
select
ColumnA = case when CheckColumn='condition' then 'result1' end
,ColumnB = case when CheckColumn='condition' then 'result2' end
Something like:
select case when CheckColumn='condition' then ColumnA='result1', ColumnB='result2' end
UPDATE
Just the same as we can do with the UPDATE statement:
update CTE
set ColumnA='result1', ColumnB='result2'
where CheckColumn='condition'
It is not possible with CASE expression.
For every column you need new CASE
It is not possible, but you could use a table value constructor as a work around to this, to store each value for columna and columnb against your check column:
SELECT t.CheckColumn,
v.ColumnA,
v.ColumnB
FROM dbo.YourTable AS t
LEFT JOIN
(VALUES
('Condition1', 'Result1', 'Result2'),
('Condition2', 'Result3', 'Result4'),
('Condition3', 'Result5', 'Result6')
) AS v (CheckColumn, ColumnA, ColumnB)
ON v.CheckColumn = t.CheckColumn;
If you have more complex conditions, then you can still apply this logic, but just use a pseudo-result for the join:
SELECT t.CheckColumn,
v.ColumnA,
v.ColumnB
FROM dbo.YourTable AS t
LEFT JOIN
(VALUES
(1, 'Result1', 'Result2'),
(2, 'Result3', 'Result4'),
(3, 'Result5', 'Result6')
) AS v (ConditionID, ColumnA, ColumnB)
ON v.ConditionID = CASE WHEN <some long expression> THEN 1
WHEN <some other long expression> THEN 2
ELSE 3
END;
The equivalent select to the update is:
select 'result1', 'result2'
. . .
where CheckColumn = 'condition';
Your select is different because it produces NULL values. There is an arcane way you can essentially do this with outer apply:
select t2.*
from . . . outer apply
(select t.*
from (select 'result1' as col1, 'result2' as col2) t
where CheckColumn = 'condition'
) t2;
This will return NULL values when there is no match. And, you can have as many columns as you would like.
What I understood from your question is that you want to update multiple columns if certain condition is true.
For such situation you have to use MERGE statements.
Example of using MERGE is as given on msdn here.
Code example:
-- MERGE statement for update.
USE [Database Name];
GO
MERGE Inventory ity
USING Order ord
ON ity.ProductID = ord.ProductID
WHEN MATCHED THEN
UPDATE
SET ity.Quantity = ity.Quantity - ord.Quantity;
More MERGE statement example here.
You could solve this maybe with a CTE or a CROSS APPLY, somehting like
DECLARE #tbl2 TABLE(inx INT, val1 VARCHAR(10),val2 VARCHAR(10));
INSERT INTO #tbl2 VALUES(1,'value1a','value1b'),(2,'value2a','value2b'),(3,'value2a','value2b');
UPDATE yourTable SET col1=subTable.val1,col2=subTable.val2
FROM yourTable
CROSS APPLY(
SELECT val1,val2
FROM #tbl2
WHERE inx=1 --YourCondition
) AS subTable

SQL server update table with missing values

I have 2 similar tables, one with all the data and the other contains a subset of the first. Every 2-3 days I need to insert in the second table the missing values, and I use this code
INSERT INTO [SRVDB2].[dbt].[curve].[curve_value]
SELECT *
FROM [SRVDB1].[dbt].[curve].[curve_value] as DB01
WHERE TargetDate >= '20150505'
and NOT EXISTS (SELECT *
FROM [SRVDB2].[dbt].[curve].[curve_value] as DB02
WHERE DB02.TargetDate = DB01.TargetDate
and DB02.[Hour] = DB01.[Hour]
and DB02.[id_Mkt] = DB01.[id_Mkt]
and DB02.[Price] = DB01.[Price]
and DB02.VoSe = DB01.VoSe
and DB02.VoBu = DB01.VoBu
)
It always worked but now I have some rows with NULL in column VoSe or VoBu and those values are not inserted correctly (even if executing only the SELECT statement seems to return all the differences). How can I handle these?
Add explicit check for NULL for both of these columns:
INSERT INTO [SRVDB2].[dbt].[curve].[curve_value]
SELECT *
FROM [SRVDB1].[dbt].[curve].[curve_value] as DB01
WHERE TargetDate >= '20150505'
and NOT EXISTS (SELECT *
FROM [SRVDB2].[dbt].[curve].[curve_value] as DB02
WHERE DB02.TargetDate = DB01.TargetDate
and DB02.[Hour] = DB01.[Hour]
and DB02.[id_Mkt] = DB01.[id_Mkt]
and DB02.[Price] = DB01.[Price]
and ((DB02.VoSe IS NULL AND DB01.VoSe IS NULL) OR DB02.VoSe = DB01.VoSe)
and ((DB02.VoBu IS NULL AND DB01.VoBu IS NULL) OR DB02.VoBu = DB01.VoBu)
)
#dotnetom's answer (+1) should work for your problem. However, making some assumptions on the problem you describe, I suspect the following would work just as well:
INSERT INTO [SRVDB2].[dbt].[curve].[curve_value]
SELECT *
FROM [SRVDB1].[dbt].[curve].[curve_value]
WHERE TargetDate >= '20150505'
EXCEPT SELECT *
FROM [SRVDB2].[dbt].[curve].[curve_value]
Use ISNULL to handle the NULL values.
NOTE: Use some random value in ISNULL function which will not come in those two columns. For example i have kept 'AAA'
SELECT *
FROM [SRVDB1].[dbt].[curve].[curve_value] as DB01
WHERE TargetDate >= '20150505'
and NOT EXISTS (SELECT *
FROM [SRVDB2].[dbt].[curve].[curve_value] as DB02
WHERE DB02.TargetDate = DB01.TargetDate
and DB02.[Hour] = DB01.[Hour]
and DB02.[id_Mkt] = DB01.[id_Mkt]
and DB02.[Price] = DB01.[Price]
and ISNULL(DB02.VoSe,'AAA') = ISNULL(DB01.VoSe,'AAA')
and ISNULL(DB02.VoBu,'AAA') = ISNULL(DB01.VoBu,'AAA')
)

Oracle SQL Insert whit Case Select

I'm new in this site and I have another question. In this case, it is from Oracle SQL, Insert operation with a CASE.
My SQL insert's code is:
INSERT WHEN (SELECT TB0083_DS_TIPODISPOSITIVO FROM TB0083_TIPODISPOSITIVO WHERE TB0083_ID_TIPODISPOSITIVO = (SELECT FOR_DISPOSITIVO FROM TFORPD01 WHERE FOR_CODIGO = &FORNECEDOR))='TIV' THEN
INTO TTRAPD01 (TRA_CODIGO,TRA_CODBARRA,TRA_CODLOC,TRA_CODCON,TRA_DATLOC,TRA_CODCAIXA,TRA_STATCOND,TRA_DT_CRIACAO,TRA_NM_USUARIOCRIACAO,TRA_DT_ALTERACAO,TRA_NM_USUARIOALTERACAO,TRA_CD_CONTA,TRA_CODCTR,TRA_TRANSACAO_ONLINE,TRA_TIV_HEXA,TRA_TIV_BINARIO,TRA_CD_DISPOSITIVO,TRA_DATSINC,TRA_ID_TPSEGREG,TRA_FORNECEDOR,TRA_STATUS)
VALUES (&NUMEROIDENTIFICADOR,&CODIGOBARRAIDENTIFICADOR,&CODIGOPONTOVENDALARM,259,SYSDATE,&CODIGOCAIXA,0,SYSDATE,&USUARIOLOGUEADO,SYSDATE,&USUARIOLOGUEADO,422,1,0,&TIVHEXA,&TIVBINARIO,423,SYSDATE,3,&FORNECEDOR,1)
ELSE
INTO TTRAPD01 (TRA_CODIGO,TRA_CODBARRA,TRA_CODLOC,TRA_CODCON,TRA_DATLOC,TRA_CODCAIXA,TRA_STATCOND,TRA_DT_CRIACAO,TRA_NM_USUARIOCRIACAO,TRA_DT_ALTERACAO,TRA_NM_USUARIOALTERACAO,TRA_CD_CONTA,TRA_CODCTR,TRA_TRANSACAO_ONLINE,TRA_TIV_HEXA,TRA_TIV_BINARIO,TRA_CD_DISPOSITIVO,TRA_DATSINC,TRA_ID_TPSEGREG,TRA_FORNECEDOR,TRA_STATUS)
VALUES (&NUMEROIDENTIFICADOR,&CODIGOBARRAIDENTIFICADOR,&CODIGOPONTOVENDALARM,259,SYSDATE,&CODIGOCAIXA,0,SYSDATE,&USUARIOLOGUEADO,SYSDATE,&USUARIOLOGUEADO,422,1,0,&TIVHEXA,&TIVBINARIO,423,SYSDATE,2,&FORNECEDOR,1);
This script doesn't found.
I need to fix it, because I need to change the value of field TRA_ID_TPSEGREG depends on the value of:
SELECT TB0083_DS_TIPODISPOSITIVO FROM TB0083_TIPODISPOSITIVO WHERE TB0083_ID_TIPODISPOSITIVO = (SELECT FOR_DISPOSITIVO FROM TFORPD01 WHERE FOR_CODIGO = &FORNECEDOR)
If value is 'TIV' then it inserts 3 in that position, else it inserts 2 in those field.
Thanks!!
There's PL/SQL INSERT WHEN command:
Try this:
INSERT FIRST
WHEN TB0083_DS_TIPODISPOSITIVO = 'TIV' THEN
INTO TTRAPD01
(
<COLUMN_NAME1>,<COLUMN_NAME2>......
)
VALUES
(
<COLUMN_VALUE1>,<COLUMN_VALUE2>.....
)
ELSE
INTO TTRAPD01
(
<COLUMN_NAME1>,<COLUMN_NAME2>......
)
VALUES
(
<COLUMN_VALUE1>,<COLUMN_VALUE2>.....
)
SELECT TB0083_DS_TIPODISPOSITIVO
FROM TB0083_TIPODISPOSITIVO
WHERE TB0083_ID_TIPODISPOSITIVO =
(SELECT FOR_DISPOSITIVO FROM TFORPD01 WHERE FOR_CODIGO = &FORNECEDOR
);
For eg:
CREATE TABLE TEST ( ID NUMBER);
INSERT FIRST
WHEN dummy = 'Y' THEN
INTO TEST
VALUES(222)
ELSE
INTO TEST
VALUES(555)
select dummy from dual;
The above query will insert 1 ROW on the very first condition satisfy. See more: >>here<<

return a default record from a sql query

I have a sql query that I run against a sql server database eg.
SELECT * FROM MyTable WHERE Id = 2
This may return a number of records or may return none. If it returns none, I would like to alter my sql query to return a default record, is this possible and if so, how? If records are returned, the default record should not be returned. I cannot update the data so will need to alter the sql query for this.
Another way (you would get an empty initial rowset returned);
SELECT * FROM MyTable WHERE Id = 2
IF (##ROWCOUNT = 0)
SELECT ...
SELECT TOP 1 * FROM (
SELECT ID,1 as Flag FROM MyTable WHERE Id = 2
UNION ALL
SELECT 1,2
) qry
ORDER BY qry.Flag ASC
You can have a look to this post. It is similar to what you are asking
Return a value if no rows are found SQL
I hope that it can guide you to the correct path.
if not exists (SELECT top 1 * FROM mytable WHERE id = 2)
select * from mytable where id= 'whatever_the_default_id_is'
else
select * from mytable where id = 2
If you have to return whole rows of data (and not just a single column) and you have to create a single SQL query then do this:
Left join actual table to defaults single-row table
select
coalesce(a.col1, d.col1) as col1,
coalesce(a.col2, d.col2) as col2,
...
from (
-- your defaults record
select
default1 as col1,
default2 as col2,
...) as d
left join actual as a
on ((1 = 1) /* or any actual table "where" conditions */)
The query need to return the same number of fields, so you shouldn't do a SELECT * FROM but a SELECT value FROM if you want to return a default value.
With that in mind
SELECT value FROM MyTable WHERE Id = 2
UNION
SELECT CASE (SELECT count(*) FROM MyTable WHERE Id = 2)
WHEN 0 THEN 'defaultvalue'
END