tsql Update with where - sql-server-2008

Currently my worktable looks like this:
Portfolio SEDOL Grouped Level
1 111 As Primary 2
1 111 Energy 2
1 122 Financial 2
2 111 Financial 1
2 133 As Primary 1
2 133 Gas 1
2 123 Oil 1
Basically what i want to do is update the worktable where grouped = "As Primary". You will see that the As Primary record has the same SEDOL as the Primary that it should match to. It has to match on the level as well as it is possible for a portfolio to only hold the secondary so will have to match on a portfolio with the same level so that there is no error.
I was guessing that the script would have to look something like this:
UPDATE #WorkTable
SET Grouped = (SELECT Grouped FROM #Worktable
WHERE ...............
WHERE (Select .............
But i'm getting confused as to what to put in my selects. A point in the right direction would be great.
Thanks

You can do this using UPDATE with JOIN. Something like this:
UPDATE t1
SET t1.Grouped = t2.Grouped
FROM #WorkTable t1
INNER JOIN #Worktable t2 ON -- a condition
WHERE -- you can also add conditions here

Related

MYSQL:Selecting SUM of a column but the column is based of another row ID

I want to have the sum of the beginning inventory of the entire year. The beginning inventory is based of the end_inventory of another month. The beginning_inventory_id contains the ID of another row which points to the end_inventory. How do I properly get the sum of the beginning_inventory of a certain year when it's based of another row's end_inventory. I have the following table
id
time_period
beginning_inventory_id
end_inventory
gross_sales
1
2020-09-01
null
1000
500
2
2020-10-01
1
2000
500
3
2020-11-01
2
3000
500
4
2020-12-01
3
4000
500
5
2021-01-01
4
5000
500
I have the following SQL query
SELECT SUM(a.gross_sales) as gross_sales, SUM(a.end_inventory) as end_inventory,
(SELECT SUM(b.end_inventory) FROM fs_summary as b WHERE a.beginning_inventory_id = b.id) as beginning_inventory
FROM fs_summary as a
WHERE YEAR(a.time_period) = 2020
Output I would like to generate is:
beginning_inventory = 6000
end_inventory = 10000
gross_sales = 2000
Instead, I am getting null on the beginning_inventory.
Any help would be great!
I am Assuming that you want to retrieve data from 1 table with self join.
SELECT SUM(a.gross_sales),SUM(a.end_inventory),SUM(b.end_inventory)
FROM fs_summary a, fs_aummary b
WHERE b.id=a.beginning_inventory_id AND YEAR(a.time_period) = 2020
using self join can help you in this situation
EDIT: You can also write this script as,
SELECT SUM(a.gross_sales),SUM(a.end_inventory),SUM(b.end_inventory)
FROM fs_summary a
INNER JOIN fs_aummary b
ON b.id=a.beginning_inventory_id
WHERE YEAR(a.time_period) = 2020
Using self-join SQL you can achieve your result instead of sub-queries.
You should specify the same table with two different names. Your query looks as below
select sum(virtual_tb.end_inventory) as 'beginning_inventory', sum(org_tb.end_inventory) as 'end_inventory', sum(org_tb.gross_sales) as 'gross_sales'
from fs_summary org_tb left join fs_aummary virtual_tb on (virtual_tb.beginning_inventory_id = org_tb.id)
where year(org_tb.time_period) = 2020;
(Approx Output)
beginning_inventory
end_inventory
gross_sales
6000
10000
2000

MySQL Select statement with several joins returns duplicated records

I have 4 tables with the following structure:
Table Groups
Groupid
groupname
groupadmin
Table GroupMembership
devid
groupid
Table GroupLocator
devid
name
pass
color
sampling
connected
forget
trace
Table GroupTracker
devid
groupid
latitude
longitude
timestamp
There is only one groupid='1' with groupname="FBorges"
Table GroupLocator has 2 records where devid points to grouid='1' on GroupMembership
GroupTracker has two records where groupid='1'
When I run the following SELECT:
SELECT GroupLocator.name, GroupLocator.color, GroupLocator.sampling,
GroupLocator.forget, GroupLocator.connected, GroupLocator.trace,
Groups.groupname, GroupTracker.latitude, GroupTracker.longitude,
GroupTracker.timestamp
FROM GroupMembership
JOIN GroupLocator ON GroupLocator.devid=GroupMembership.devid
JOIN Groups ON Groups.groupid=GroupMembership.groupid
JOIN GroupTracker ON GroupTracker.groupid=GroupMembership.groupid
WHERE GroupMembership.groupid=1;
I get the result:
name color sampling forget connected trace groupname latitude longitude timestamp
PCBorges 2 1 45 0 1 FBorges -22.883639 -42.822542 2020-01-08 20:29:24
Test 3 2 45 1 0 FBorges -22.883639 -42.822542 2020-01-08 20:29:24
PCBorges 2 1 45 0 1 FBorges -22.873639 -42.322542 2020-01-11 16:56:30
Test 3 2 45 1 0 FBorges -22.873639 -42.322542 2020-01-11 16:56:30
What I hope to get is:
name color sampling forget connected trace groupname latitude longitude timestamp
PCBorges 2 1 45 0 1 FBorges -22.883639 -42.822542 2020-01-08 20:29:24
Test 3 2 45 1 0 FBorges -22.883639 -42.822542 2020-01-08 20:29:24
EDIT: Removed my previous speculation after structure and data was provided and wrote a new answer:
I believe that you want to JOIN GroupTracker on devid instead of on groupid. Groupid 1 matches both rows in the GroupTracker table, so it will provide two results for each 1 row in GroupMemebership. Devid only matches one row. A correct JOIN is more efficient than your current GROUP BY solution (in comments) and may also produce more consistent results as your database grows.
SELECT gl.name, gl.color, gl.sampling,
gl.forget, gl.connected, gl.trace,
g.groupname, gt.latitude, gt.longitude,
gt.timestamp
FROM GroupMembership AS gm
JOIN GroupLocator AS gl ON gm.devid = gl.devid
JOIN Groups AS g ON gm.groupid = g.groupid
JOIN GroupTracker AS gt ON gm.devid = gt.devid
WHERE gm.groupid=1
;
I aliased all your tables so the query is much shorter and hence faster to write. I also swapped positions of all your JOIN clauses. I prefer to have the left table on the left side and the right table on the right side. Makes it easier to read. These two changes are not important. It's only style. The query will work perfectly without them.

FInd missing row based on Column data -MySQL

I am currently working on a.Net web form solution which generates a brief service report for admins to monitor the services done by technicians.As of now , i am having some trouble in coming up with an efficient SQL (for MySQl) which return data rows along with the missing rows based on the SertvicePrtNum , which is in order.
For Example :-
This is my raw data in the table :-
Id ServiceRptNum Customer_ID Date of Service
---- ------------- ----------- ---------------
1 1001 3 09/10/1997
2 1003 8 10/06/2005
3 1005 1 21/02/2003
4 1007 7 1/06/2011
5 1010 4 4/11/2012
6 1002 2 16/01/2003
Here the ServiceRptNum , 1004 is missing in the table. So i want the db to return the result as : -
Id ServiceRptNum Customer_ID Date of Service
---- ------------- ----------- ---------------
1 1001 3 09/10/1997
2 1002 2 16/01/2003
3 1003 8 10/06/2005
- 1004 - -
4 1005 1 21/02/2003
- 1006 - -
5 1007 7 1/06/2011
- 1008 - -
- 1009 - -
6 1010 4 4/11/2012
Here , the sql additionally generated 1004,1006,1008,1009 since it cannot find those records.
Please note that the Id is automatically generated (auto_increment)while insert of the data.But the Service ReportNum is not , this is to enable the admin to add the service report later on with the manually generated report Num (report num in the hardcopy of the company Servicebook).
You basically need to invent a constant, sequential stream of numbers and then left join your real data to them. For this method to work, you need a table with enough rows in it to generate a counter big enough:
select ID, 1000+n as servicerptnum, customer_id, `Date of Service` from
(
SELECT #curRow := #curRow + 1 AS n
FROM somebigtable
JOIN (SELECT #curRow := 0) r
WHERE #curRow<100
) numbergen
LEFT JOIN
tablewithmissingservicerptnum
ON
servicerptnum = 1000+n
You need to alter some things in the code above because you never told us the name of your table with missing rptnums. You also need to utilise another table in your database with more rows than this table because the way this method works is to count the rows in the bigger table, giving each a number. If you don't have any table bigger than this one, we can probably get enough rows by cross joining a smaller table to itself or by using this table. Replace somebigtable with thistable CROSS JOIN thistable where this table is the name of the table with missing servicerptnums
If you want just the rows that are missing, add a WHERE servicerptnum is null to the end of the sql
Edit, I see you've changed your numbering from:
1001
1002
...
1009
10010
To:
1009
1010
The join condition used to be servicerptnum = concat('100', cast(n as varchar)), it is now servicerptnum = 1000+n..
Look here for ideas on how to generate a group of continuous integers, then select from that left outer join your table. You should get a row for every number but all the values will be null for the missing numbers.

compare column of two rows of same table in mysql

I have a table name player_history containing history of player. in this table having column player_id, Final_position,meeting_code,race_no and beaten_time. If a player stood a first or second position the time will be same there are meeting code one day and in each meeting code there are maximum 10 races.
I want to select those records where 1st and second position beaten time are not same.
player_id Meeting_Code race_no final_position beaten_time
1 0001 1 1 2
2 0001 1 2 2
1 0001 2 1 5
2 0001 2 2 6
... so on
Output should be:
player_id Meeting_Code race_no final_position beaten_time
1 0001 2 1 5
2 0001 2 2 6
Also if it is not correct I want to update records of first position only.
Let table name be Test. Try to put Self Join or something like this:
Select t1.player_id t1.Meeting_Code t1.race_no t1.final_position t1.beaten_time
From Test t1
LEFT JOIN Test t2 ON t1.beaten_time != t2.beaten_time.
Try like this. It might work.
Check this it will work
SELECT *
FROM table_name
GROUP BY player_id
HAVING count(beaten_time) = 1;
Try It:
select b.player_id,b.meeting_code,b.race_no,b.final_position,b.beaten_time
from player_history a,player_history b
where a.race_no = b.race_no and a.beaten_time != b.beaten_time;

T-SQL query procedure-insert

I am wondering if any of you would be able to help me. I am trying to loop through table 1 (which has duplicate values of the plant codes) and based on the unique plant codes, create a new record for the two other tables. For each unique Plant code I want to create a new row in the other two tables and regarding the non unique PtypeID I link any one of the PTypeID's for all inserts it doesnt matter which I choose and for the rest of the fields like name etc. I would like to set those myself, I am just stuck on the logic of how to insert based on looping through a certain table and adding to another. So here is the data:
Table 1
PlantCode PlantID PTypeID
MEX 1 10
USA 2 11
USA 2 12
AUS 3 13
CHL 4 14
Table 2
PTypeID PtypeName PRID
123 Supplier 1
23 General 2
45 Customer 3
90 Broker 4
90 Broker 5
Table 3
PCreatedDate PRID PRName
2005-03-21 14:44:27.157 1 Classification
2005-03-29 00:00:00.000 2 Follow Up
2005-04-13 09:27:17.720 3 Step 1
2005-04-13 10:31:37.680 4 Step 2
2005-04-13 10:32:17.663 5 General Process
Any help at all would be greatly appreciated
I'm unclear on what relationship there is between Table 1 and either of the other two, so this is going to be a bit general.
First, there are two options and both require a select statement to get the unique values of PlantCode out of table1, along with one of the PTypeId's associated with it, so let's do that:
select PlantCode, min(PTypeId)
from table1
group by PlantCode;
This gets the lowest valued PTypeId associated with the PlantCode. You could use max(PTypeId) instead which gets the highest value if you wanted: for 'USA' min will give you 11 and max will give you 12.
Having selected that data you can either write some code (C#, C++, java, whatever) to read through the results row by row and insert new data into table2 and table3. I'm not going to show that, but I'll show how the do it using pure SQL.
insert into table2 (PTypeId, PTypeName, PRID)
select PTypeId, 'YourChoiceOfName', 24 -- set PRID to 24 for all
from
(
select PlantCode, min(PTypeId) as PTypeId
from table1
group by PlantCode
) x;
and follow that with a similar insert.... select... for table3.
Hope that helps.