I have two tables that aren't really associated, but need to be combined. So I'm using union all on the two tables. The unioned tables are ordered by date, so rows from one table are dispersed among rows from the other table. What I need to do is get a running count of a column so I can group elements.
To explain further, table A holds dates of when a container is emptied, while table B holds daily entries for content of the container. I need to union the two tables so I have one table where I can get the sum of the information for a container before the container is emptied.
So I need something like this:
Table A:
Location_ID Empty Date
123 3/2/13
123 3/10/13
123 4/1/13
Table B:
PSI Entry Date Location_ID
120 2/28/13 123 (same for all)
130 3/1/13
100 3/8/13
110 3/9/13
200 3/18/13
180 3/20/13
So the unioned table after some magic would look like:
Table C...:
Location_ID Date PSI Emptied
123 2/28/13 120 0
123 3/1/13 130 0
123 3/2/13 null 1
123 3/8/13 100 0
123 3/9/13 110 0
123 3/10/13 null 1
123 3/18/13 200 0
123 3/20/13 180 0
123 4/1/13 null 1
What I need to do is have a grouping such that I can have a table like this
Table C_b
Location_ID Date PSI Emptied Group
123 2/28/13 120 0 1
123 3/1/13 130 0 1
123 3/2/13 null 1 1
123 3/8/13 100 0 2
123 3/9/13 110 0 2
123 3/10/13 null 1 2
123 3/18/13 200 0 3
123 3/20/13 180 0 3
123 4/1/13 null 1 3
How can I get that grouping in that way? I have to make it work in SQL Server 2008. I have tried using Count, and Rank, and Row_Number. But the problem with those is that it won't do a running count, it will just say the total count in each row.
Try this query:
DECLARE #MyTable TABLE(
EntryDate DATE NOT NULL,
Emptied BIT NOT NULL
);
INSERT INTO #MyTable (EntryDate,Emptied)
VALUES
('2013-01-01',0),
('2013-01-02',0),
('2013-01-03',1),
('2013-01-04',0),
('2013-01-05',0),
('2013-01-06',1),
('2013-01-07',0),
('2013-01-08',0),
('2013-01-09',1);
DECLARE #TableWithRowNum TABLE(
EntryDate DATE NOT NULL,
Emptied BIT NOT NULL,
RowNum INT PRIMARY KEY
);
INSERT INTO #TableWithRowNum (EntryDate,Emptied,RowNum)
SELECT crt.*,ROW_NUMBER() OVER(ORDER BY crt.EntryDate) AS RowNum
FROM #MyTable crt;
WITH RecCTE
AS(
SELECT
crt.EntryDate,
crt.Emptied,
crt.RowNum,
1 AS Grp
FROM #TableWithRowNum crt
WHERE crt.RowNum=1
UNION ALL
SELECT
crt.EntryDate,
crt.Emptied,
crt.RowNum,
CASE WHEN prev.Emptied=1 THEN prev.Grp+1 ELSE prev.Grp END
FROM #TableWithRowNum crt INNER JOIN RecCTE prev ON crt.RowNum=prev.RowNum+1
)
SELECT * FROM RecCTE
OPTION(MAXRECURSION 0); -- Default value for MAXRECURSION is 100
GO
Results:
EntryDate Emptied RowNum Grp
---------- ------- ------ ---
2013-01-01 0 1 1
2013-01-02 0 2 1
2013-01-03 1 3 1
2013-01-04 0 4 2
2013-01-05 0 5 2
2013-01-06 1 6 2
2013-01-07 0 7 3
2013-01-08 0 8 3
2013-01-09 1 9 3
Related
a simple task, but I can't figure it out. There is a Table:
id
name
sum
place
1
Alex
210
0
2
Bob
250
0
3
Sam
190
0
4
Bill
290
0
5
Jack
210
0
I need to UPDATE the PLACE
according to the maximum SUM and then the id
Those are the request :
SELECT id, name, sum, place FROM tableORDER BYsumDESC,id ASC;
According to this request, update the semi PLACE from 1++
Those places 1, 2, 3 and further throughout the table
Like this:
id
name
sum
place
1
Alex
210
3
2
Bob
250
2
3
Sam
190
5
4
Bill
290
1
5
Jack
210
4
SET #n_place := 0;
UPDATE `table` SET `place` = #n_place := #n_place + 1 ORDER BY `sum` DESC, `id` ASC;
I have a table below named deposit
dep_id
deposit_amount
comp_id
1
100
1
2
100
1
3
300
2
4
200
2
5
100
2
6
500
3
When I update the table with the query below I get the following table, which is not what I want
UPDATE deposit
SET deposit_amount = (SELECT SUM(deposit_amount) - 50)
WHERE comp_id =1
What the query above does is to subtract 50 from each of the corresponding comp_id
dep_id
deposit_amount
comp_id
1
50
1
2
50
1
3
300
2
4
200
2
5
100
2
6
509
3
But the table below is what I need.
Because seeing the first table and with the query I provided where comp_id =1, we have 100 + 100 = 200, and then 200 - 50 = 150. So because comp_id has 1 IDs two times, therefore we have 75 and 75 because 75 +75 is 150. So we have the table below, which is what I need.
dep_id
deposit_amount
comp_id
1
75
1
2
75
1
3
300
2
4
200
2
5
100
2
6
500
3
The amount supposed to be evenly split amongst the deposits that share a comp_id, even if they weren't before.
Please how do I write the query to suit the table I need? Help!
You can divide the 50 by the count of the records for this id:
UPDATE deposit d1,
(SELECT *, count(*) over (partition by d2.comp_id) as c FROM deposit d2) x
SET d1.deposit_amount = (SELECT SUM(d1.deposit_amount) - 50/x.c)
WHERE d1.comp_id =1
see: DBFIDDLE
This is probably a easy one, but for the life of me I can't seem to figure it out.
This is my table:
uid | userID | trackID | carID | highscoreDate | highscore
-----------------------------------------------------------------
1 1 1 1 [date] 123
2 1 1 1 [date] 44
3 2 2 1 [date] 222
4 2 1 1 [date] 28
5 1 2 1 [date] 17
I would like to get the SUM of the highest highscores for each user and track. In the data above that would give:
user 1: 140
user 2: 250
How about using a subselect first.
Something like
SELECT userID, SUM(highscore)
FROM (
SELECT userID, trackID, MAX(highscore) highscore
FROM MyTable
GROUP BY userID, trackID
) s
GROUP BY userID
SQL Fiddle DEMO
For example
id staff_id skill_id mainskill
1 1 24 1
2 1 24 0
3 1 7 0
4 4 24 0
5 4 18 0
6 6 8 0
7 6 18 1
I would like the result to contain only the tuples with a skill_id that is present only once in all the data. In other words I want to retrieve the tuples containing the skill_ids that are only possessed by a single staff member.
And so the desired output is:
id staff_id skill_id mainskill
3 1 7 0
6 6 8 0
Thanks in advance :).
You can do it with GROUP BY and HAVING, like this:
SELECT
MAX(id) as id,
MAX(staff_id) as staff_id,
skill_id,
MAX(mainskill) as mainskill
FROM MyTable
GROUP BY skill_id
HAVING COUNT(1)=1
This is my table structure:
rec_id product_id quantity quantity_in quantity_out balance stock_date status
1 2 342 NULL 17 325 2009-10-23 1
2 2 325 NULL 124 201 2009-10-23 1
3 1 156 NULL 45 111 2009-10-23 1
4 2 201 NULL 200 1 2009-10-23 1
5 2 1 NULL 1 0 2009-10-23 1
6 1 111 NULL 35 76 2009-10-23 1
All I want is the last transaction done for a given product: product_id, quantity, quantity_out and balance from this table.
Example, there are 2 transaction done for product 2 (ids 1 & 2):
final balance for product_id 2 is 0 -> stored in rec_id 5
final balance for product_id 1 is 76 -> stored in rec_id 6
Final result/output should be like this:
recid productid quantity quantityin quantityout balance stock_date status
5 2 1 NULL 1 0 2009-10-23 1
6 1 111 NULL 35 76 2009-10-23 1
You can find the latest record for each product like:
select max(rec_id) as MaxRec
from YourTable
group by product_id
Using a subquery, you can retrieve the latest rows for their product:
select *
from YourTable
where rec_id in (
select max(rec_id) as MaxRec
from YourTable
group by product_id
)
Here's a single query with no subqueries:
SELECT main.*
FROM YourTable main
LEFT JOIN YourTable newer
ON newer.product_id = main.product_id AND newer.rec_id > main.rec_id
WHERE newer.rec_id IS NULL;
You can tweak the field list however you want--make sure you select fields from main, not newer, which should be all null.