How to append and update new data to a SQL table without overwriting the old data? - sql

Let's say we've got the following (very simplified compared to my real use case) table:
Campaign ID
Campaign Name
Impressions
Clicks
Purchases
111111
Alfa
5000
120
3
111112
Beta
7000
140
6
111113
Gamma
6000
90
3
With the usage of temporary SQL table we can pull out a new data for campaign Delta and also updated data for the ongoing campaign Gamma, but campaigns Alfa and Beta are historical and therefore not available in the temporary table and we want to leave them as they are.
New data pulled through a query could look like this:
Campaign ID
Campaign Name
Impressions
Clicks
Purchases
111113
Gamma
9000
160
7
111114
Delta
1000
40
0
How would I formulate a query that will bring me this result:
Campaign ID
Campaign Name
Impressions
Clicks
Purchases
111111
Alfa
5000
120
3
111112
Beta
7000
140
6
111113
Gamma
9000
160
7
111114
Delta
1000
40
0
I am sure this might be a common problem, but so far I wasn't able to find an easily understandable solution.
Apologies if this seems very simple.
And thanks in advance for any help!

Have one query that selects from the new table
Have another query that selects records from your old table that don't have the same keys as any records in your new table
UNION the two queries together

Related

Spreading the values to other rows but still respecting the total sum

I have a dataset as below:
date employee products sales
20210101 ben 5 laptop
20210101 ben 10 monitor
20210201 tim 15 laptop
20210301 tim 10 monitor
What I would like to do is to add another field/column as the working hours for these employees. Depending on how many rows the employee have on that particular day (it could be up to 5-10 rows), the number of working hours should be spread equally, but the total should always be a maximum of 6 hours per day.
The desired output should be:
date employee products sales hours
20210101 ben 5 laptop 3
20210101 ben 10 monitor 3
20210201 tim 15 laptop 6
20210301 tim 10 monitor 6
I don't have any good idea to perform this query. If anyone could give me a hint on a method or an approach to tackle this, I would really appreciate.
Pretty sure redshift supports window functions..
SELECT *,
6.0/COUNT(*) OVER(PARTITION BY date, employee) as hours
FROM dataset

Is it possible to write an SQL query that does a 'find and replace' with two tables?

Details
I have two tables:
Reservations Table (I separated them by date just for organizational purposes)
Date Name Room Name Seats Requested
01/1/2020 John 1 10
01/1/2020 Rebecca 3 30
01/1/2020 Haley 6 55
01/2/2020 David 1 10
01/2/2020 Rebecca 3 30
01/2/2020 Dasher 4 30
01/3/2020 Roger 4 40
01/3/2020 Doe 5 50
01/3/2020 Smith 3 30
Room Table
Name Seats
1 10
2 20
3 30
4 40
5 50
6 60
Each room will only appear ONCE for each date or won't appear at all. They are also on a "best fit" basis, as can see in the middle 3, both Rebecca and Dasher needed 30 seats, but since Rebecca got room 3, which is the best fitted room for her (30 seats) Dasher has to get the next "best" fit room for his 30 requested seats which is room 4 that has 40 seats available.
Now I have to "remove" a room from both tables: so the tables after like that would be something like this:
Reservations Table (AFTER REMOVING ROOM 3)
Date Name Room Name Seats Requested
01/1/2020 John 1 10
01/1/2020 Rebecca 30
01/1/2020 Haley 6 55
01/2/2020 David 1 10
01/2/2020 Rebecca 30
01/2/2020 Dasher 4 30
01/3/2020 Roger 4 40
01/3/2020 Doe 5 50
01/3/2020 Smith 30
Room Table (AFTER REMOVING ROOM 3)
Name Seats
1 10
2 20
4 40
5 50
6 60
So I want to write an SQL Query that will find the appropriate room that will be available to the people that got their room removed in the reservations table.
For example For date 1 (01/1/2020) Rebecca loses her room 3. Which means her next best room she can use is room 4.
For date 2 we see Rebecca again loses her room 3, except this time, room 4 is being used, which means her next best room she can use is room 5.
For date 3, Smith loses his room 3. But since room 4 and 5 is being used, his next available room he can use is room 6
Expected output
My ideal output would be something like this:
Date Name Room Name Seats Requested
01/1/2020 Rebecca 4 30
01/2/2020 Rebecca 5 30
01/3/2020 Smith 6 30
Here's what I tried
I've already been able to remove the rooms as shown above, so that won't be necessary. Below is the SQL query I'm trying, but I'm getting syntax errors.
SELECT date,name,roomName,seatsRequested
FROM reservations table1
where not exists (select 1
from Room table2
where table1.roomName = table2.Name)
AND MIN(table1.seatsRequested<=table2.seats)
GROUP BY date;
First I select the stuff I want to display. Then I want to find the rooms that don't exist in for a specific date.
Then I want to find the first room that will fit, so I use the "MIN()" function to do that, because for example, for date 1, if I didn't use the MIN() function, it would return two values: Room 4 and Room 5 because both of them are available for Rebecca to use. Using "MIN()" would hopefully only return Room 4.
Finally I group the query by the date so it applies to each date.
Just to clarify, I don't need any data inserted yet, just returned. If it's easier to simply just insert the data, then that is fine, but getting the returned stuff is really what I'm looking for.
I'm getting syntax errors (A plethora, things like GROUP BY isn't allowed, or like can't use MIN like that). And when I fix those errors I get nothing back. Not sure how to do this. Is this possible in SQL?
Each person will reserve a room separately. For example, Jim wants to reserve a room with 25+ seats for 01/1/2020. Rooms 1,3,6 are already reserved, room 2 does not match, so rooms 4 and 5 are matching and available, and room 4 must be shown/reserved for him. You do not need to investigate the reservations for another dates. Jim simply enters "01/1/2020" and "25 places" and receives "room 4". That's all. Is it? – Akina
#Akina yes, that's right. I was using java for my inputs and removal. now I just need SQL to return me the values for each one and then I'll use java to insert them. but if SQL has the functionality perhaps I don't need to use JAVA at all. – PSU Change
SELECT Room.Name
FROM Room
LEFT JOIN Reservation ON Room.Name = Reservation.RoomName
AND Reservation.Date = {entered date}
WHERE Reservation.RoomName IS NULL
AND Room.Seats >= {entered amount}
ORDER BY Room.Seats ASC LIMIT 1
If (in current data state) Jim enters 01/1/2020 as date and 25 as amount then the query will return 4. If Jim agreed then this room is reserved and according row is inserted into Reservations. If he not agreed he may alter the amount and/or date and maybe receive another room or refuse to reserve a room at all.
Also you may remove LIMIT 1 - in such case Jim will see 2 variants for reservation, rooms 4 and 5. He'll select one of them by some reasons (for example, reservation price may influence), and according info will be added into the table.

Normalize monthly payments

First, sorry for my bad English. I'm trying to normalize a table in a pension system where subscribers are paid monthly. I need to know who has been paid and who has not and how much they've been paid. I believe I'm using SQL Server. Here's an example:
id_subscriber id_receipt year month pay_value payment type_pay
12 1 2016 January 100 80 1
13 1 2016 January 100 100 1
14 1 2016 January 100 100 1
12 2 2016 February 100 100 2
13 2 2016 February 100 80 1
But I'm not happy repeating the year and the month for every single subscriber. It doesn't seem right. Is there a better way to store this data?
EDIT:
The case is as follows: this company has many subscribers who must pay monthly and payment can be in various ways. They produce a single receipt for many customers, and each customer that receipt may be paying one or more installments.
These are my other tables:
tbl_subscriber
id_suscriber(PK) first_name last_name address tel_1 tel_2
12 Juan Perez xxx xxx xxx
13 Pedro Lainez xxx xxx xxx
14 Maria Lopez xxx xxx xxx
tbl_receipt
id_receipt(PK) value elaboration_date deposit_date
1 1,000.00 2015-09-16 2015-09-20
2 890.00 2015-12-01 2015-12-18
tbl_type_paym
id type description
1 bank xxxx
2 ventanilla xxx
This basically seems fine. You could split dates out into a separate table and reference that, but that strikes me as a kind of silly way to do it. I would recommend storing the month as an integer instead of a varchar column though. Besides not storing the same string over and over you can more reasonably do comparisons.
You could also use date values, although that might not be worth the trouble when you don't want greater granularity than the month.

SQL: Display joined data on a day to day basis anchored on a start date

Perhaps my title is misleading, but I am not sure how else to phrase this. I have two tables, tblL and tblDumpER. They are joined based on the field SubjectNumber. This is a one (tblL) to many (tblDumpER) relationship.
I need to write a query that will give me, for all my subjects, a value from tblDumpER associated with a date in tblL. This is to say:
SELECT tblL.SubjectNumber, tblDumpER.ER_Q1
FROM tblL
LEFT JOIN tblDumpER ON tblL.SubjectNumber=tblDumpER.SubjectNumber
WHERE tblL.RandDate=tblDumpER.ER_DATE And tblDumpER.ER_Q1 Is Not Null
This is straightforward enough. My problem is the value RandDate from tblL is different for every subject. However, it needs to be displayed as Day1 so I can have tblDumpER.ER_Q1 as Day1 for every subject. Then I need RandDate+1 As Day2, etc until I hit either null or Day84. The 'dumb' solution is to write 84 queries. This is obviously not practical. Any advice would be greatly appreciated!
I appreciate the responses so far but I don't think that I'm explaining this correctly so here is some example data:
SubjectNumber RandDate
1001 1/1/2013
1002 1/8/2013
1003 1/15/2013
SubjectNumber ER_DATE ER_Q1
1001 1/1/2013 5
1001 1/2/2013 6
1001 1/3/2013 2
1002 1/8/2013 1
1002 1/9/2013 10
1002 1/10/2013 8
1003 1/15/2013 7
1003 1/16/2013 4
1003 1/17/2013 3
Desired outcome:
(Where Day1=RandDate, Day2=RandDate+1, Day3=RandDate+2)
SubjectNumber Day1_ER_Q1 Day2_ER_Q1 Day3_ER_Q1
1001 5 6 2
1002 1 10 8
1003 7 4 3
This data is then going to be plotted on a graph with Day# on the X-axis and ER_Q1 on the Y-axis
I would do this in two steps:
Create a query that gets the MIN date for each SubjectNumber
Join this query to your existing query, so you can perform a DATEDIFF calculation on the MIN date and the date of the current record.
I'm not entirely sure of what it is that you need, but perhaps a calendar table would be of help. Just create a local table that contains all of the days of the year in it, then use that table to JOIN your dates up?

MS Access, Excel, SQL, and New Tables

I'm just starting out with MS Access 2010 and have the following setup. 3 excel files: masterlist.x (which contains every product that I sell), vender1.x (which contains all products from vender1, I only sell some of these products), and vender2.x (again, contains all products from vender2, I only sell some of these products). Here's an example data collection:
masterlist.x
ID NAME PRICE
23 bananas .50
33 apples .75
35 nuts .87
38 raisins .25
vender1.x
ID NAME PRICE
23 bananas .50
25 pears .88
vender2.x
ID NAME PRICE
33 apples .75
35 nuts .87
38 raisins .25
49 kiwis .88
The vender lists get periodically updated with new items for sell and new prices. For example, vender1 raises the price on bananas to $.75, my masterlist.x would need to be updated to reflect this.
Where I'm at now: I know how to import the 3 excel charts into Access. From there, I've been researching if I need to setup relationships, create a macro, or a SQL query to accomplish my goals. Not necessarily looking for a solution, but to be pointed in the right direction would be great!
Also, once the masterlist.x table is updated, what feature would I use to see which line items were affected?
Update: discovered SQL /JOIN/ and have the following:
SELECT * FROM master
LEFT JOIN vender1
ON master.ID = vender1.ID
where master.PRICE <> vender1.PRICE;
This gives me the output (for the above scenario)
ID NAME PRICE ID NAME PRICE
23 bananas .50 23 bananas .75
What feature would instead give me:
masterlist.x
ID NAME PRICE
23 bananas .75
33 apples .75
35 nuts .87
38 raisins .25
Here is a heads up since you were asking for ideas to design. I don't really fancy your current table schema. The following queries are built in SQL Server 2008, the nearest syntax that I could get in sqlfiddle to MS Access SQL.
Please take a look:
SQLFIDDLE DEMO
Proposed table design:
vendor table:
VID VNAME
1 smp farms
2 coles
3 cold str
4 Anvil NSW
product table:
PID VID PNAME PPRICE
203 2 bananas 0.5
205 2 pears 0.88
301 3 bananas 0.78
303 3 apples 0.75
305 3 nuts 0.87
308 3 raisins 0.25
409 4 kiwis 0.88
masterlist:
ID PID MPRICE
1 203 0.5
2 303 0.75
3 305 0.87
4 308 0.25
Join queries can easily update your masterlist now. for e.g.:
When the vendor updates their prices for the fruits they provide you. Or when they stop supply on that product. You may use where clauses to add the conditions to the query as you desire.
Query:
SELECT m.id, p.vid, p.pname, p.pprice
FROM masterlist m
LEFT JOIN product p ON p.pid = m.pid
;
Results:
ID VID PNAME PPRICE
1 2 bananas 0.5
2 3 apples 0.75
3 3 nuts 0.87
4 3 raisins 0.25
Please comment. Happy to help you if have any doubts.