Updating a column in postgresql based on a specific date - sql

I'm wondering if I could use trigger with PostgrSQL to update a column where I do have column with date type and on this date I would like to updated another column in another table.
To make it more clear
I do have 2 tables
Works_locations table
walphid wnumberid locationid
DRAR 1012 101
PAPR 1013 105
PAHF 1014 105
ETAR 1007 102
DRWS 1007 102
the locationsid attribute refers to "locid' in Locations table which is down
locid locname
101 Storage
102 Gallary A
103 Gallary B
104 Gallary C
105 Lobby
Exhibition table
exhid exhname description strtdate endDate
101 Famous Blah Blah 2013-07-15 2013-10-13
and here are bridge table to connect the exhibition table with the locations table
locationsid exhibitid
102 102
103 101
104 103
Now Each exhibition has some works and should be placed in one of the locations table.
On the 'endDate' column in the exhibition table, which is a date data type, I would like to update 'locationid' column in the Works locations table to be placed in another location.
In another words. Each exhibitions has some works and this works are placed in one of the locations. at the ending date of the exhibition, I would like to change the locations, and specifically, I would like the work to be returned to the storage.
Any idea how would I do this action with postgresql?
Regard

PostgreSQL does not have a built-in task scheduler. Even if there was a scheduler, the commands it ran wouldn't be triggers, they'd just be be procedures run by a scheduler.
You can't write triggers that fire at some arbitrary time.
You will need to use cron, Task Scheduler, PgAgent, or similar to run the statements at the desired time. Or you could write a script that checks when the next event is, sleeps until then, runs the desired command and marks that event as done, and sleeps until the next event.

Related

The IDs change in the column

I am quite a novice in programming and I kind need your help regarding SQL and an issue I notice.
I have a table:
date, ID, secondary ID, expenses
jul2020 258 0004 1000
jul2020 xxx xxxx xxx
...... .... .... .....
aug2020 258 0008 2000
aug2020 xxx xxxx xxx
aug2020 500 0004 1000
Id and secondary should be unique and always matching. But I notice that they are not. It's either correct the ID or the secondary ID. I want to sum all the D column per unique ID.
Thanks for reading and if you have any ideas would be very helpful
UPDATE: everything is numeric even ID. It's like this. As you can see we have different dates (but for the same date multiple customers). I notice that customer 258 for secondary ID 0004 during the years the ID or the secondary ID changes. And I wan to assign the same ID as the first date and the same secondary ID as the first date ( or any day just to be consistent). I want to to do this cause I want to know how many expenses each customer has during the years. There are like 50m obs.

SQL - SAP HANA - Use only first entry in Column table (based on date/time)

I have some tables on SAP HANA and „create column table“ to combine multiple „raw tables“.
In one table, there are duplicate rows, to be more specific, every Information (column) is the same but the date/time is not.So the source System has this weird habit to create one entry, several times (which is wrong). I do not have the possibility to manipulate data in the source System.
The table looks something like:
Table name: Testsubject_status
Column: Status....info....Timestamp
Test me...............bla.......05.01.2017 05:05:00
Test me...............bla......01.01.2017 11:15:00
Test him………..blub…..01.01.2017 11:17:00
Test her ………..blab.....01.01.2017 11:25:00
Test me ………..bla.......01.01.2017 11:35:00
Test it………......blue......01.01.2017 12:15:00
Test me ………..bla.......07.01.2017 12:15:00
All duplicates after the first entry (date/time whise) should be not considered in the newly created table.
Table name: Testsubject_status_NEW
Column: Status....info....Timestamp
Test me...............bla......01.01.2017 11:15:00
Test him………..blub…..01.01.2017 11:17:00
Test her ………..blab.....01.01.2017 11:25:00
Test it………......blue......01.01.2017 12:15:00
This problem does appear multiple times, not only with Test me.
Is the solution something like:
Select
xxx AS "tri"
yyy AS "tre"
zzz AS "tru"
Case when Testsubject_status.Status Count > 1 Then "take first entry"
From ...
Where …
???
I am glad for every help or advice.
Based on the description it should be sufficient to aggregate for the maximum date:
SELECT tri, tre, tru,
max(timestamp)
FROM
....
That works if the „de-duplication“ indeed should happen based on all remaining columns except timestamp.

Is it possible to match the "next" unmatched record in a SQL query where there is no strictly unique common field between tables?

Using Access 2010 and its version of SQL, I am trying to find a way to relate two tables in a query where I do not have strict, unique values in each table, using concatenated fields that are mostly unique, then matching each unmatched next record (measured by a date field or the record id) in each table.
My business receives checks that we do not cash ourselves, but rather forward to a client for processing. I am trying to build a query that will match the checks that we forward to the client with a static report that we receive from the client indicating when checks were cashed. I have no control over what the client reports back to us.
When we receive a check, we record the name of the payor, the date that we received the check, the client's account number, the amount of the check, and some other details in a table called "Checks". We add a matching field which comes as close as we can get to a unique identifier to match against the client reports (more on that in a minute).
Checks:
ID Name Acct Amt Our_Date Match
__ ____ ____ ____ _____ ______
1 Dave 1001 10.51 2/14/14 1001*10.51
2 Joe 1002 12.14 2/28/14 1002*12.14
3 Sam 1003 50.00 3/01/14 1003*50.00
4 Sam 1003 50.00 4/01/14 1003*50.00
5 Sam 1003 50.00 5/01/14 1003*50.00
The client does not report back to us the date that WE received the check, the check number, or anything else useful for making unique matches. They report the name, account number, amount, and the date of deposit. The client's report comes weekly. We take that weekly report and append the records to make a second table out of it.
Return:
ID Name Acct Amt Their_Date Unique1
__ ____ ____ ____ _____ ______
355 Dave 1001 10.51 3/25/14 1001*10.51
378 Joe 1002 12.14 4/04/14 1002*12.14
433 Sam 1003 50.00 3/08/14 1003*50.00
599 Sam 1003 50.00 5/11/14 1003*50.00
Instead of giving us back the date we received the check, we get back the date that they processed it. There is no way to make a rule to compare the two dates, because the deposit dates vary wildly. So the closest thing I can get for a unique identifier is a concatenated field of the account number and the amount.
I am trying to match the records on these two tables so that I know when the checks we forward get deposited. If I do a simple join using the two concatenated fields, it works most of the time, but we run into a problem with payors like Sam, above, who is making regular monthly payments of the same amount. In a simple join, if one of Sam's payments appears in the Return table, it matches to all of the records in the Checks table.
To limit that behavior and match the first Sam entry on the Return table to the first Sam entry on the Checks table, I wrote the following query:
SELECT return.*, checks.*
FROM return, checks
WHERE (( ( checks.id ) = (SELECT TOP 1 id
FROM checks
WHERE match = return.unique1
ORDER BY [our_date]) ));
This works when there is only one of Sam's records in the Return table. The problem comes when the second entry for Sam hits the Return table (Return.ID 599) as the client's weekly reports are added to the table. When that happens, the query appropriately (for my purposes) only lists that two of Sam's checks have been processed, but uses the "Top 1 ID" record to supply the row's details from the Return table:
Checks_Return_query:
Checks.ID Name Acct Amt Our_Date Their_Date Return.ID
__ ____ ____ ____ _____ ______ ________
1 Dave 1001 10.51 2/14/14 3/25/14 355
2 Joe 1002 12.14 2/28/14 4/04/14 378
3 Sam 1003 50.00 3/01/14 3/08/14 433
4 Sam 1003 50.00 4/01/14 3/08/14 433
In other words, the query repeats the Return table info for record Return.ID 433 instead of matching Return.ID 599, which is I guess what I should expect from the TOP 1 operator.
So I am trying to figure out how I can get the query to take the two concatenated fields in Checks and Return, compare them to find matching sets, then select the next unmatched record in Checks (with "next" being measured either by the ID or Our_Date) with the next unmatched record in Return (again, with "next" being measured either by the ID or Their_Date).
I spent many hours in a dark room turning the query into various joins, and back again, looking at functions like WHERE NOT IN, WHERE NOT EXISTS, FIRST() NEXT() MIN() MAX(). I am afraid I am way over my head.
I am beginning to think that I may have a structural problem, and may need to write the "matched" records in this query to another table of completed transactions, so that I can differentiate between "matched" and "unmatched" records better. But that still wouldn't help me if two of Sam's transactions are on the same weekly report I get from my client.
Are there any suggestions as to query functions I should look into for further research, or confirmation that I am barking up the wrong tree?
Thanks in advance.
I'd say that you really need another table of completed transactions, it could be temporary table.
Regarding your fears "... if two of Sam's transactions are on the same weekly report ", you can use cursor in order to write records "one-by-one" instead of set based transaction.

Better SQL query to remove equivalent rows

Guys, I'm new at SQL and can't figure out the "right way" to do the last part of a query. I have a table which contains a list of items and their equivalents. There are essentially twice as many rows as needed, and I'm trying to find a SQL way to select 1/2 of the entries so there are no duplicates.
Starting Table with duplicates:
Item Name EquivItem
---- ------ ----------
100 bubba 106
103 gump 109
106 shrimp 100
109 grits 103
And the resulting table would be:
Item Name EquivItem
----- ----- ----------
100 bubba 106
103 gump 109
I was using a couple nested loops in sequential code to filter out the duplicates, but finally wrote a query that works but feels like a hack.
I'm arbitrarily using a WHERE (Item < EquivItem) to select only one of the rows. The actual tables are a bit more complex and I'm afraid there may be a case where this doesn't work.
SELECT *
FROM T
WHERE Item < EquivItem
I'm trying to take some time to figure out the right way to do things before I develop too many bad habits. Any suggestions? Thanks.
Is it possible for more than two items to be equivalent, such as 100 = 103 = 106? Can this happen?
Item Name EquivItem
---- ------ ----------
100 bubba 103
103 gump 106
106 shrimp 103
As long as the the equivalents can't be chained together, and always have a 1-to-1 relationship, your solution looks perfectly fine to me.
If this scenario can happen, I would first scrub the data to make sure that all the EquivItems refer to the lowest Item ID in the chain... and then your original query would still do the job.

Best Approach to Processing SQL Data problem

I have a Data intensive problem which requires a lot of massaging and data manipulation and I'm putting this out there to see if anyone has an idea as to how to approach it.
In simplest form. I have a lot of tables which can be joined together to give me a price listing for dentists and how much each charges for a procedure.
so we have multiple tables that looks like this.
Dentist | Procedure1 | Procedure2 | Procedure3 | .........| Procedure?
John | 500 | 342 | 434 | .........| 843
Dave | 343 | 434 | 322 | NULLs....|
Mary | 500 | 342 | 434 | .........| 843
Linda | 500 | 342 | Null | .........| 843
Dentists can have different number of procedures and different pricing for each procedures. But there are a lot of Dentists that have the same number of procedures and the same rates that goes with it. Internally, we create a unique ID for each of these so-called fee listings.
like John would be 001, Dave would be 002, but Mary would be fee 001 and Linda would be 003
It's not so bad if I have to deal with this data once but these fee listings comes in flat files (csvs) which i basically have to DTS up to a SQL server to work with. and they come on a monthly bases. The pricing could change from month to month for each dentist which then would put them in a different unique ID internally.
Can someone shed some light on as to how to best approach this problem so that it's most efficient to process on a monthly basis without having to do tons of data manipulation?
what's the best approach to finding out the duplicates of the fee listings?
How do i keep track of updating a Dentist's fee listing incase they change their rates the next month? if Mary decides to charge a different fee for procedure2, then she would have a different unique ID internally. how do i keep track of that on a monthly bases without having to delete everything and re-insert?
There are a few million fee listings that I'm working with and some have standard rules that are based on zipcodes and some are just unique fee listings, what's the approach here?
I can write some kind of ad-hoc .net program to work with it but it's a lot of data and working straight in SQL server would be easier for me.
any help would be great, thanks guys.
You probably need to unpivot the data to normalize it - so that you end up with:
Doctor: DoctorID, DoctorDetails...
FeeSchedule: DoctorID, ScheduleID, EffectiveDate, OtherDetailAtThisLevel...
FeeScheduleDetail: ScheduleID, ProcedureCode, Fee, OtherDetailAtThisLevel...
When the data comes in for a doctor, it is pivoted, a new schedule is created and the detail rows are created from the unpivoted data.
SSIS has an unpivot component which is fine - you would load the schedule first and then the detail. If the format varies significantly, you might need a custom data source or just avoid SSIS.
This system would keep track of new schedules for doctors. If the schedule is identical for a doctor, you could simply not insert it.
If this logic is extensive, you could load the data to staging tables (SSIS or whatever) and do all this in SQL (T-SQL also has an UNPIVOT operator). That can have advantages in that the code is all in one place and can do all its operations in sets.
Regarding the zip codes, if the doctor doesn't have a fee, are these like usual and customary fee? This could simply be determined from the zip code of the doctor row. In this case you have a few options. You can overlay the doctor fee schedule over a zip code fee schedule:
ZipCodeSchedule: ZipScheduleID, ZipCode, EffectiveDate
ZipCodeScheduleDetail: ZipScheduleID, ProcedureCode, Fee
Or you could save this in the regular feeschedule (potentially with some kind of flag that it was defaulted to the UCR).