Difficulty in creating update totals query on same table - sql

Consider the following table:
ID nonUniqueID value total
--------------------------
1 12345 5 x
2 12345 10 x
3 789 20 x
4 789 5 x
I need to make a query something like this (psuedo SQL), which will work within Access 2007:
UPDATE table
SET total = SUM(value)
WHERE nonUniqueID IS SAME;
The result should be as follows:
ID nonUniqueID value total
--------------------------
1 12345 5 15
2 12345 10 15
3 789 20 25
4 789 5 25
I've tried group bys, but I got odd results that quite frankly, I could not interpret. Does anybody know how I could achieve something like this?

Not sure if this works in Access or not, but give it a try:
update table t1
inner join (
select nonUniqueID, sum(value) as SumValue
from table
group by nonUniqueID
) t2 on t1.nonUniqueID = t2.nonUniqueID
set t1.total = t2.SumValue
Update: Based on this question, it looks like it is not going to work. But give it a shot! If it doesn't, you can use the approach suggested in that question.

Another possible option:
update t
set total = (select SUM(value) from table where nonUniqueID = t.nonUniqueID)
from table t

Related

SQL GROUP BY and HAVING but have results include column not included in GROUP BY to provide more detail?

Sample data:
Week
Client
Amount
1
A
20
1
B
20
2
A
20
2
B
10
3
C
40
I want a query where if the total for the week is 40 or more, include those rows in the result set, but ALSO include the Client.
So the results would look something like this:
Week
Client
Amount
1
A
20
1
B
20
3
C
40
I am prepared to do this via two queries and EXISTS, but I was checking to see if there was something more elegant. I've tried using a GROUP BY and HAVING but no such luck as I don't think I can use having on the aggregate but also show the client detail.
You can do:
select *
from (
select *, sum(amount) over(partition by week) as sa
from t
) x
where sa >= 40

In PostgreSQL, Creating and appending a new column

I'd like to get an average per type then join the aggregated table as a new column in the original table. Here's a visualization and code of what I'm attempting to do:
-- The original table --
ID | Cnt | Type
1 5 A
1 6 A
2 4 B
-- New Table --
ID | Cnt | Type | Avg
1 5 A 5.5
1 6 A 5.5
2 4 B 4.0
The code I have written thus far is the following:
select AVG(Cnt)
from old
group by(type)
right join on old
But, obviously it's not correct since a syntax error is raised. What would be the fix for this? I apologize in advance if my question is similar to an already existing one.
Use window functions:
select o.*, avg(cnt) over (partition by type)
from old o;

Creating sequentially increasing groups based on number change

How can I code this in oracle SQL?
I have the below data
Current Result
I want to generate a result that looks like the following:
Desired Result
So, I essentially want the group ID to increase as the row number changes back to 1. I am trying to use row_number, rank() and partition functions but it is not working properly. Desperate for help!
Thanks
EDIT (by Gordon):
The original question had the data in question. It is much, much better to have the values in the question as text than to refer to an image, so I'm adding it back in:
Code Row Number
214 1
214 2
210 1
210 2
210 3
214 1
I want to generate a result that looks like the following:
Code Row Number Group Id
214 1 1
214 2 1
210 1 2
210 2 2
210 3 2
214 1 3
In order to do what you want, you need a column that specifies the ordering of the rows in the table. Let me assume that you have an id or creation date or something similar.
If so, then what you want is simply a cumulative sum of the number of times that the second column is 1:
select t.*,
sum(case when RowNumber = 1 then 1 else 0 end) over (order by id) as GroupId
from t;
it's still not clear which field is ID because if it's rownumber as you said it's not going work the way that you have in expected output
create table test (id int , code int, rownumber int);
insert into test values (1,214,1);
insert into test values (2,214,2);
insert into test values (3,210,1);
insert into test values (4,210,2);
insert into test values (5,210,3);
insert into test values (6,214,1);
select s.code, sum(add_group) over (order by id) from (
select id, code, case when rownumber=1 then 1 else 0 end as add_group from test
order by id
) s
CODE SUM(ADD_GROUP)OVER(ORDERBYID)
1 214 1
2 214 1
3 210 2
4 210 2
5 210 2
6 214 3
btw the asnwer of #Gordon Linoff works better and exactly as you want but you need add additional field for order by

Select only the persons that have both values

I have a table with 2 columns:
ClientID | PhoneType
1 | 4
1 | 4
1 | 5
2 | 4
3 | 5
I'm trying to wright a query to only show the client who have both phone types.
So output should only show client ID 1
As you notice, client 1 has two type '4' PhoneTypes, so I'm trying not to use a GroupBy/HavingCount of method to narrow the result down. Which were the only examples I could find.
Something like...
SELECT x.ClientID
FROM (
SELECT DISTINCT ClientID, PhoneType FROM [Table A]
) AS x
GROUP BY x.ClientID
HAVING COUNT(x.PhoneType) = 2
DISTINCT is used to remove duplicates from the COUNT in case the client has 2 or more phones of the same type.
I don't have access to a SQL Server currently, but it seems like you should be able to use the following, which is a little simpler than Gavin's answer:
SELECT ClientID
FROM [Table A]
GROUP BY ClientID
HAVING COUNT(DISTINCT PhoneType) = 2
Not entirely sure that count distinct works in HAVING, but I don't see why it wouldn't...

Rows in columns

I have this table:
Id Kind
1 MODEL
1 MOTOR
2 MODEL
2 MOTOR
3 MOTOR
4 MODEL
And I want to insert into anothe table:
IdModel IdMotor
1 1
1 2
1 3
2 1
2 2
2 3
4 1
4 2
4 3
I know how to do it with cursors, but it's indeed very slow. I've tried with union but it looks like today is not my best day!
I also know this can be done in SQL 2005 with pivot, but I have to do it with SQL Server 2000.
Any Transact-SQL guru out there with a good and quick query?
Thanks in advance!
Looks like this will work:
INSERT Table2
SELECT model.id, motor.id
FROM
Table model,
Table motor
WHERE
model.Kind = 'MODEL'
and motor.Kind = 'MOTOR'
INSERT INTO AnotherTable
SELECT [IdModel]
, [IdMotor]
FROM (
SELECT [IdModel] = ID
FROM ATable
WHERE Kind = 'MODEL'
) md
CROSS APPLY
(
SELECT [IdMotor] = ID
FROM ATable
WHERE Kind = 'MOTOR'
) mt