Storing multiple values from SQL query to stored procedure variable - sql

I want to do something like the example below
ColumnAVal = Select ColumnA from TableA where....
ColumnBVal = Select ColumnB from TableA where....
Select * from TableB where ColumnC = (value from ColumnA)
Select * from TableC where ColumnD = (value from ColumnB)
I have to get the values from TableA query which has one hefty where clause. And I have to get about 20 different columns from TableA. So, above example won't be a good idea. I am trying to find a better way to save these values, that doesn't require me to use same where clause 20 times.
Basically idea is to get the 20 or so columns from the TableA and save those as variables for later use. That way I can create just one query to save the column values instead of calling it twenty times.
E.g.
#QuantityAvailable = SELECT TOP 1 WLPS_Qty_Available FROM
TBL_Warehouse_Location_Parts_Spec, TBL_Location_Master,
TBL_Warehouse_Master WHERE WLPS_Parts_Spec_ID = #PartSpecID AND WLPS_Part_Type_ID IN ( 0, #PartTypeID ) AND WLPS_Active_Flag = 'Y' AND ( WLPS_Location_ID = #LocationID )
I have to run the same query again and again 20 times. And I would prefer I don't have to, to save some processing.

declare #ColumnAVal varchar(20);
declare #ColumnBVal varchar(20);
select #ColumnAVal = ColumnA , #ColumnBVal = ColumnB from TableA where....
The values used are from the last row in the returned set so it only makes sense when the select returns a single row or it's suitably ordered (less good).

--I have to assume that the where clause is different in each case
Select * from TableB where ColumnC IN (Select ColumnA from TableA where....)
Select * from TableC where ColumnD IN (Select ColumnB from TableA where....)

Related

How to do an update on a query having union in postgrsql?

I have 2 tables name test and test_snapshop. in test table i am saving the current data and in test_snapshot i am saving older data. Now i need to do an update against some id values.theer is a chance that some ids exist in test and some in snapshot table.
I tried like this
update test
set column1=value,
column2=value,
column3=value
where column4 in(1,2,3)
union
update test_snapshot
set column1=value,
column2=value,
column3=value
where column4 in(1,2,3)
Both tables have same no and name of column.
The above query is not as expected. what I am doing wrong in this query. can any one help me in this.
I am new to postgresql.
Although I voted to close as a typo, you can express this in Postgres using a single statement. I might go for:
with ids as (
select *
from (values (1), (2), (3)) v(id)
),
t as (
update test
set column1 = value,
column2 = value,
column3 = value
where column4 in (select i.id from ids i)
)
update test_snapshot
set column1 = value,
column2 = value,
column3 = value
where column4 in (select i.id from ids i);
With this structure, you only need to list the id values once.

Count value across multiple columns

I am looking to count the number of times set of values occurred in a table. These values could occur in up to 10 different columns. I need to increment the count regardless of which column it is in. I know how I could count if they were all in the same column but not spanning multiple columns.
Values can be added in any order. I have about a thousand
Cpt1 Cpt2 Cpt3 Cpt4 Cpt5
63047 63048 63048 NULL NULL
I would want to for this row I'd expect this as the result
63047 1
63048 2
You could use a union all call to treat them as one column:
SELECT col, COUNT(*)
FROM (SELECT col1 FROM mytable
UNION ALL
SELECT col2 FROM mytable
UNION ALL
SELECT col3 FROM mytable
-- etc...
) t
GROUP BY col
It's not entirely clear what your table exactly looks like, but I'm guessing that what you're looking for is:
SELECT row_count = COUNT(*),
row_count_with_given_value = SUM ( CASE WHEN field1 = 'myValue' THEN 1
WHEN field2 = 'myValue' THEN 1
WHEN field3 = 'myValue' THEN 1
WHEN field4 = 'myValue' THEN 1 ELSE 0 END)
FROM myTable
Assuming the fieldx columns are not NULL-able, you could write it like this too:
SELECT row_count = COUNT(*),
row_count_with_given_value = SUM ( CASE WHEN 'myValue' IN (field1, field2, field3, field4) THEN 1 ELSE 0 END)
FROM myTable
Something like this might work (after adapting to your value domain and data types):
create table t1
(i1 int,
i2 int,
i3 int);
insert into t1 values (1,0,0);
insert into t1 values (1,1,1);
insert into t1 values (1,0,0);
declare #i int = 0;
select #i = #i + i1 + i2 + i3 from t1;
print #i;
drop table t1;
Output is: 5
Many databases support lateral joins, of one type of another. These can be used to simplify this operation. Using the SQL Server/Oracle 12C syntax:
select v.cpt, count(*)
from t cross apply
(values (cpt1), (cpt2), . . .
) v(cpt)
where cpt is not null
group by v.cpt;

SQL: Difference between rows

I am trying to find the difference between two numbers corresponding to the same ID, but with two different conditions. For example,
Column A Column B Column C
1234 3 True
1234 5 False
5678 10 True
5678 15 False
So basically i want to find the difference in Column B when column A is the same but Column C is different.
If we can assume
2 rows for a given value in ColumnA
expected result is only 1 row returned per unique colA value
columnC will never be null...
Column B will never match, and if they do, you don't want the record returned.
We can use a self join checking for matches on column A, no matches on column C and so that we don't get a row each for 1234 of 2 and -2.
SELECT Z.ColumnA, Z.B-Y.B
FROM TableName Z
INNER JOIN tableName Y
on Z.ColumnA = Y.ColumnA
and Z.ColumnC <> Y.ColumnC
and Z.ColumnB > Y.ColumnB
you could also do this with a window function using lead and look ahead to the next record. but I don't know if your RDBMS supports window functions.
select t1.ColumnA, t1.ColumnB-t2.ColumnB diff from
tab t1, tab t2
where t1.columnA = t2.columnA and t1.ColumnC='True' and t2.ColumnC='False'
If your table name is myTable, I believe you can join the table with itself and on Column A and then select a difference in Column B when Column C is not equal to itself. So something like this
SELECT X.ColumnB - Y.ColumnB as Diff
FROM myTable as X
inner join
myTable as Y
on X.ColumnA=Y.ColumnA
WHERE X.ColumnC <> Y.ColumnC
You could use a self join
select a.column_A, a,column_B, b.column_B, a.column_B . b.column_B
from my_table a
inner join my_column b where a.column_a = b.column_a and a.column_c <> b_column_c
If you RDBMS supports window functions
;with cte as (
Select *
,Change = ColumnB-Lag(ColumnB,1) over (Partition By ColumnA Order By (Select null))
,TrueFalse = Lag(ColumnC,1) over (Partition By ColumnA Order By (Select null))
From #YourTable
)
Select ColumnA
,Change
From cte
Where Change<>0
and TrueFalse<>ColumnC
Returns
ColumnA Change
1234 2
5678 5
This one subtracts the "true" rows from the "false" rows, while preserving all true rows.
SELECT true.columna, true.columnb, COALESCE(false.columnb, 0) - true.columnb AS difference
FROM
(SELECT *
FROM t
WHERE columnc = "true") true
LEFT JOIN
(SELECT *
FROM t
WHERE columnc = "false) false
ON true.columna = false.columna
The coalesce clause will account for cases in which there is no false row. Without it you will end up trying to subtract from NULL.
If you're using Oracle, take a look at User Defined aggregate functions. If you define a function called diff(), then you can use select column_A, diff(column_B) from my_table group by column_A, but remember that the implementation of diff needs special care as different ordering will generate different results.

If value return the value. If a record not exists or when column is null, return 0 in Sql Server - different ways

I want to return 0 if there is no record or if the Column1 is null.
select #var = Column1
from myschema.mytable
where Id = #suppliedId;
select isnull(#var, 0);
The above code outputs 0 if if Column1 is null. Or if a row is not found
Whereas I tried to save some keystrokes but it resulted in,
select isnull(Column1, 0)
from myschema.mytable
where Id = #suppliedId;
The above code outputs null if Column1 is null or when there is no row
Any ideas what is wrong here ? Or is there any shorter way of writing the first code ?
You can do
SELECT #var = ISNULL(MAX(Column1), 0)
FROM myschema.mytable
WHERE Id = #suppliedId;
A scalar aggregate always returns a single row even if the underlying query returns zero rows.
Not really saving key strokes, but something like this could help :-)
SELECT TOP 1 tbl.field
FROM
(
SELECT 0 AS inx, 'no record' AS field
--if only one row is possible, than set '1' literally
UNION SELECT ROW_NUMBER() OVER(ORDER BY mytable.orderfield), ISNULL(mytable.Land,'is null')
FROM mytable
WHERE IDENTITY = #suppliedID
) AS tbl
ORDER BY tbl.inx DESC

What is the fastest/easiest way to tell if 2 records in the same SQL table are different?

I want to be able to compare 2 records in the same SQL table and tell if they are different. I do not need to tell what is different, just that they are different.
Also, I only need to compare 7 of 10 columns in the records. ie.) each record has 10 columns but I only care about 7 of these columns.
Can this be done through SQL or should I get the records in C# and hash them to see if they are different values?
You can write a group by query like this:
SELECT field1, field2, field3, .... field7, COUNT(*)
FROM table
[WHERE primary_key = key1 OR primary_key = key2]
GROUP BY field1, field2, field3, .... field7
HAVING COUNT(*) > 1
That way you get all records with same values for field 1 to 7, along with the number of occurrences.
Add the part between brackets to limit your search for duplicates, either with OR, or with IN (...).
IF EXISTS (SELECT Col1, Col2, ColEtc...
from MyTable
where condition1
EXCEPT SELECT Col1, Col2, ColEtc...
from MyTable
where condition2)
BEGIN
-- Query returns all rows from first set that are not column for column
-- also in the second (EXCEPT) set. So if there are any, there will be
-- rows returned, which meets the EXISTS criteria. Since you're only
-- checking EXISTS, SQL doesn't actually need to return columns.
END
No hash is necessary. Normal equality comparison is enough:
select isEqual = case when t1.a <> t2.a or t1.b <> t2.b bbb then 1 else 0 end
SELECT
CASE WHEN (a.column1, a.column2, ..., a.column7)
= (b.column1, b.column2, ..., b.column7)
THEN 'all 7 columns same'
ELSE 'one or more of the 7 columns differ'
END AS result
FROM tableX AS a
JOIN tableX AS b
ON t1.PK = #PK_of_row_one
AND t2.PK = #PK_of_row_two
Can't you just use the DISTINCT keyword? All duplicates will not be returned, so each row you receive is unique (and different from the others).
http://www.mysqlfaqs.net/mysql-faqs/SQL-Statements/Select-Statement/How-does-DISTINCT-work-in-MySQL
So you could make this query:
SELECT DISTINCT x,y,z FROM RandomTable WHERE x = something
Which will only return one row for each unique x,y,z combination.