I tried using pivot in SQL Server, but I'm just going in circles with no good results.
I have this result set that could vary in number of records:
ForeignID
Name
Value
1
A
1
1
B
2
1
C
3
2
D
4
How can I do a SELECT to get this for all rows with ForeignID of 1:
ForeignID
A
B
C
1
1
2
3
suppose I have 100000 records in A table and 1000 records in B table. both have primary/foreign key relationship. now i want to update a column value for first 100 records in table A with column value from table B first record. similary i want to update all the 100000 records in table A as a batch 100 records for 1000 times with values from table B.
no. of records updated per batch is 100 i.e. 100000/1000=100
Lets assume you have table_a with 20 rows with a unique id column and you want to update the value column:
CREATE TABLE table_a (id, value) AS
SELECT LEVEL, CAST(NULL AS NUMBER(8,0)) FROM DUAL CONNECT BY LEVEL <= 20;
And table_b with 5 rows containing the values you want to update from:
CREATE TABLE table_b (id, value) AS
SELECT LEVEL, LEVEL FROM DUAL CONNECT BY LEVEL <= 5;
Then, you can use a correlated UPDATE statement:
UPDATE table_a a
SET value = (SELECT value
FROM table_b b
WHERE CEIL(a.id*5/20) = b.id);
or a MERGE statement:
MERGE INTO table_a a
USING table_b b
ON (CEIL(a.id*5/20) = b.id)
WHEN MATCHED THEN
UPDATE
SET value = b.value;
Both statements result in:
ID
VALUE
1
1
2
1
3
1
4
1
5
2
6
2
7
2
8
2
9
3
10
3
11
3
12
3
13
4
14
4
15
4
16
4
17
5
18
5
19
5
20
5
db<>fiddle here
I have a table with 4 columns ID, c1, c2 and LOT. ID is the primary key. For every record when c1 is 5 I want to auto-generate a number for LOT which will be a sequence starting from 1 for each distinct value of c2.
So if c1 is not 5, LOT remains null. But if c1 is 5 then for every record where c2=1 I want to populate LOT with an auto-incrementing sequence starting from 1.
Ex:
ID c1 c2 LOT
1 3
2 5 1 1
3 5 1 2
4 5 1 3
5 4
Then do the same for a different value of c2. So if c2 is 2, have another bunch of auto-incrementing LOT numbers starting from 1:
ID c1 c2 LOT
6 3
7 5 2 1
8 5 1 4
9 5 2 2
10 5 2 3
We are using MSSQL 2014 Enterprise Ed. Would table-partitioning be useful or do I need to create special tables for each distinct value of C2?
not with an identity field, you can use a trigger instead.
There is no way of doing this using the Identity feature, however, consider using a Instead of trigger to manually manage the values like you want.
You could use the logic to generate LOT in a query or view:
SELECT ID, C1, C2,
CASE
WHEN C1<>5 OR C2 IS NULL THEN NULL
ELSE COUNT(*) OVER (PARTITION BY C1, C2 ORDER BY ID ROWS BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW)
END AS LOT
FROM D
ORDER BY ID
Given a table generated with (ID, C1, C2):
CREATE TABLE D (ID INT PRIMARY KEY IDENTITY, C1 INT, C2 INT)
INSERT D VALUES (3,NULL),
(5,1),
(5,1),
(5,1),
(4,NULL),
(3,NULL),
(5,2),
(5,1),
(5,2),
(5,2)
The query produces the output indicated above:
ID C1 C2 LOT
1 3
2 5 1 1
3 5 1 2
4 5 1 3
5 4
6 3
7 5 2 1
8 5 1 4
9 5 2 2
10 5 2 3
The statement used to generate LOT, COUNT(*) OVER (PARTITION BY C1, C2 ORDER BY ID ROWS BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW, simply counts the number of rows before and including the current row where C1 and C2 are equal to the current row. For instance, for Row 4, the tuple (c1,c2)=(5,1) is observed in 3 records before and including that row (rows 2, 3, and 4), so LOT=3.
Thank you everyone for the suggestions to use a trigger (all up-voted). It turns out (as I mentioned in a comment above) an article that came up on the side-bar (SQL Server unique auto-increment column in the context of another column) shows a detailed construction of the proper INSTEAD OF INSERT trigger. The author mentions that it is "Not tested", and indeed there IS a slight error (a missing GROUP BY ParentEntityID in the WITH clause) but anybody copying the code would get an error that is obvious to fix. Probably not kosher to be correcting that post here, but the other question is 6 years old.
I have values in SQL Server derived column sorted as descending i.e.
id Count OR id Count OR id Count
1 4 1 5 1 11
2 4 2 2 2 1
3 4 3 1 3 1
4 4 4 1 4 1
5 4 5 1 5 1
Now I want to select top 3 maximum values. How can I select so that query returns consistent result every time.
For example if values of Count are same which id's should be returned as top 3 maximums, similarly if 3rd value is matched with other values and if 2nd value is matched with other values then which id's should be returned by the query. And the result should be consistent every time I execute the query.
The with ties argument of the top function will return all the of the rows which match the top values:
select top (3) with ties id, count from table1
order by count desc
Alternatively, if you wanted to return 3 values only, but make sure they are always the same 3 values, then you will need to use something else as a tie-breaker. In this case, it looks like your id column could be unique.
select top (3) id, count from table1
order by count desc, id
I am in need of stored procedure, I have searched but I didn't get any relevant code.
My requirement is the stored procedure wants to loop the first subquery based on inner subquery.
Select *
from StockInward,
Setup
where StockInward.StockLocation=Setup.Id
AND ProductId in( Select ProductId
from ProductOutward
where Orderid ='38')
The sample table data and output below:
Product Outward table
Id Orderid Productid Qty
1 38 7 2
2 38 6 1
Stockinward table
Id ProductId BranchId Qty
1 7 1 12
2 6 1 2
3 7 2 2
Setup table
BranchId Branchname
1 Xyz
2 ABC
The output need to be:
ProductId Branches
7 Xyz(12) Abc(2 )
6 Xyz(2) -