Repeat a Field Value - sql

A data table I'm working in has multiple rows of costs for an item that need to be summed but, one of the values from another field needs to be repeated on that summed row. For example:
+-------------+------+-------------+
| ITEM NUMBER | COST | OTHER VALUE |
+-------------+------+-------------+
| 1 | 10 | -1 |
| 2 | 4 | -1 |
| 1 | -2 | 123 |
| 3 | 3 | -1 |
And lots more...
The results should look like:
+-------------+------+-------------+
| ITEM NUMBER | COST | OTHER VALUE |
+-------------+------+-------------+
| 1 | 8 | 123 |
| 2 | 4 | -1 |
| 3 | 3 | -1 |
I could make a table of item numbers with, "Other values," greater than zero but, am wondering if there's a cooler way.
Thanks for the help!

Simple aggregation should work for your use case:
select item_number, sum(cost) cost, max(other_value) other_value
from mytable
group by item_number

Related

How to write a sql script that cursors through a table and inserts into a different table

I am new to sql server i have the following table structure that contains more than a thousand rows.
But for example purposes this is what it would look like
Table Import
+------+---------+------------+------------+------------+------------+------------+
| Name | Code | SocksTotal | GlovesTotal| JeansTotal | ShirtsTotal| shoesTotal |
+------+---------+------------+------------+------------+------------+------------+
| OT | 45612 | 2 | 1 | 0 | 1 | 4 |
| OT | 1234 | 0 | 1 | 0 | 0 | 0 |
| US | 45896| 0 | 0 | 0 | 0 | 0 |
+------+---------+------------+------------+------------+------------+------------+
and a second table called Items follows
+------+---------+
| ID | Item |
+------+---------+
| 1 | socks |
| 2 | Gloves|
| 3 | Jeans |
| 4 | Shirts|
| 5 | shoes |
+------+---------+
from the above tables i need to write a script that would be inserted into a different table called ImportItems_Summary.
the expected output is
+------+---------+------------+------------+
| Id | Code | Items_id |Import_total|
+------+---------+------------+------------+
| 1 | 45612 | 1 | 2 |
| 2 | 45612 | 2 | 1 |
| 3 | 45612 | 4 | 1 |
| 4 | 45612 | 5 | 4 |
| 5 | 1234 | 2 | 1 |
+------+---------+------------+------------+
as you can see here that code 45612 now has 4 entries into the ImportItems_summary table where the items is not equal to 0 and the Items_id is linked to the Items table ID column.
How can i achieve the above output?.. I read up and saw a cursor might help but i am not sure how to implement this
One method uses cross apply to unpivot the columns of the unnormalized table to rows, then brings the items table with a join, and finally inserts in the target table:
insert into ImportItems_Summary (code, items_id, import_total)
select im.code, it.items_id, x.import_total
from import im
cross apply (values
('socks', sockstotal),
('gloves', glovestotal),
('jeans', jeanstotal),
('shirts', shirtstotal),
('shoes', shoestotal)
) x(item, import_total)
inner join items it on it.item = x.item

How to count unique occurences of column in Big Query

Given a table such as:
| ID | Value |
|-------------|
| 1 | "some" |
| 1 | "some" |
| 1 | "value"|
| 2 | "some" |
| 3 | "some" |
| 3 | "value |
| 3 | "value |
How can I count the number of unique occurrences of value for each ID?
So you end up with a table such as:
| ID | Value | number |
|-------------|--------|
| 1 | "some" | 2 |
| | "value"| 1 |
| 2 | "some" | 1 |
| 3 | "some" | 1 |
| | "value | 2 |
I attempted to use OVER(PARTITION BY ID order by Value) to separate the table by IDs and count the separate values. However this counts the number of unique occurences, but then adds them together. So I end up with a table such as:
| ID | Value | number |
|-------------|--------|
| 1 | "some" | 2 |
| 1 | "some" | 2 |
| 1 | "value"| 3 |
| 2 | "some" | 1 |
| 3 | "some" | 1 |
| 3 | "value | 3 |
| 3 | "value | 3 |
Is there a way to count the unique values like the second example I gave?
Below is for BigQuery Standard SQL
#standardSQL
SELECT id, value, COUNT(1) number
FROM `project.dataset.table`
GROUP BY id, value
with result
Row id value number
1 1 some 2
2 1 value 1
3 2 some 1
4 3 value 2
5 3 some 1

SQL generate unique ID from rolling ID

I've been trying to find an answer to this for the better part of a day with no luck.
I have a SQL table with measurement data for samples and I need a way to assign a unique ID to each sample. Right now each sample has an ID number that rolls over frequently. What I need is a unique ID for each sample. Below is a table with a simplified dataset, as well as an example of a possible UID that would do what I need.
| Row | Time | Meas# | Sample# | UID (Desired) |
| 1 | 09:00 | 1 | 1 | 1 |
| 2 | 09:01 | 2 | 1 | 1 |
| 3 | 09:02 | 3 | 1 | 1 |
| 4 | 09:07 | 1 | 2 | 2 |
| 5 | 09:08 | 2 | 2 | 2 |
| 6 | 09:09 | 3 | 2 | 2 |
| 7 | 09:24 | 1 | 3 | 3 |
| 8 | 09:25 | 2 | 3 | 3 |
| 9 | 09:25 | 3 | 3 | 3 |
| 10 | 09:47 | 1 | 1 | 4 |
| 11 | 09:47 | 2 | 1 | 4 |
| 12 | 09:49 | 3 | 1 | 4 |
My problem is that rows 10-12 have the same Sample# as rows 1-3. I need a way to uniquely identify and group each sample. Having the row number or time of the first measurement on the sample would be good.
One other complication is that the measurement number doesn't always start with 1. It's based on measurement locations, and sometimes it skips location 1 and only has locations 2 and 3.
I am going to speculate that you want a unique number assigned to each sample, where now you have repeats.
If so, you can use lag() and a cumulative sum:
select t.*,
sum(case when prev_sample = sample then 0 else 1 end) over (order by row) as new_sample_number
from (select t.*,
lag(sample) over (order by row) as prev_sample
from t
) t;

SQL Statement to show columns multiple times

I have a table containing an integer column that represents a work place, an integer column that represents the number of workpieces finished at that workplace and a date column.
I want to create a query that creates rows of the following type
location int | date of Max(workpiece) | max workpieces | Min(Date) | workpieces (Min(Date)) | max(Date) | workpieces (Max(Date))
So i want a row for each location containing the date of the day where the most pieces where finished plus the amount of the pieces, the oldest date and the pieces finished on that day and the newest date plus the number of pieces finished that day.
Do I have to use joins, to join the table with itself 3 times each given one of the criteria and then join on location? Is The GROUP BY Operator involved, which I don't quite get the hang of?
EDIT: Here's some sample data
+-------+-----------+-----------+-------------------+
| id | location | amount | date |
+-------+-----------+-----------+-------------------+
| 1 | 1 | 10 | 01.01.2016 |
| 2 | 2 | 5 | 01.01.2016 |
| 3 | 1 | 6 | 02.01.2016 |
| 4 | 2 | 35 | 02.01.2016 |
| 5 | 1 | 50 | 03.01.2016 |
| 6 | 2 | 20 | 03.01.2016 |
+-------+-----------+-----------+-------------------+
I want my output to look like this:
loc | dateMaxAmount| MaxAmount | MinDate | AmountMinDate | MaxDate | MaxDateAmount
1 | 03.01.2016 | 50 | 01.01.2016| 10 | 03.01.2016| 50
2 | 02.01.2016 | 35 | 01.01.2016| 5 | 03.01.2016| 20
I am using MS Access.

Marking records with 1 on first occurence of unique value

I have a table that I'd like to add a column to that shows a 1 on the first occurrence of a given value for the record within the dataset.
So, for example, if I was using the ID field as where to look for unique occurrences, I'd want a "FirstOccur" column (like the one below) putting a 1 on the first occurrence of a unique ID value in the dataset and just ignoring (leaving as null) any other occurrence:
| ID | FirstOccur |
|------|--------------|
| 1 | 1 |
| 1 | |
| 1 | |
| 2 | 1 |
| 2 | |
| 3 | 1 |
| 4 | 1 |
| 4 | |
I have a working 2-step approach that first applies some ranking sql that will give me something like this:
| ID | FirstOccur |
|------|--------------|
| 1 | 1 |
| 1 | 2 |
| 1 | 3 |
| 2 | 1 |
| 2 | 2 |
| 3 | 1 |
| 4 | 1 |
| 4 | 2 |
..and I just apply some update SQL to null any value above 1 to get the desired result.
I was just wondering if there was a (simpler) one-hit approach.
Assuming you have a creation date or auto incremented id or something that specifies the ordering, you can do:
update t
set firstoccur = 1
where creationdate = (select min(creationdate)
from t as t2
where t2.id = t.id
);