How to create SCD type 2 with no new output row when condition is met - ssis

I need to create SCD type 2 in order to store addresses. I need to track changes in columns City, ZipCode, Type and ValidTo. The column ValidTo says the date to which the address was valid (it takes the value from the database). I'm trying to get my head around how to create SCD type 2 so that it won't create a new row when value in column ValidTo doesn't equal to '2100-01-01'.
Here is what I get:
The address is inactive in the database but in my dimension address table it's still active since there's a row with null value in DateTo column.
I'm racking my brain how not to insert a new row when a condition is met.
AdressID
ad_id
City
ZipCode
Type
ValidTo
DateFrom
DateTo
1
100
Warsaw
02-414
registered
2100-01-01
2022-11-28
2022-12-05
2
100
Warsaw
02-414
registered
2022-12-05
2022-12-05
null

Related

How to add a tag based on a column value

I'm trying to join two tables and select certain columns to display in the output including a 'flag' if a certain transaction amount is greater than or equal to 100. The flag would return a 1 if it is, else null.
I thought I could achieve this using a CASE in my SELECT but it only returns one record every time since it returns the first record that meets this condition. How do I just create this 'FLAG' column during my join easily?
SELECT payment_id, amount, type,
CASE
WHEN amount >= 100 THEN 1
ELSE NULL
END AS flag
FROM trans JOIN customers ON (user_id = cust_id)
JOIN bank ON (trans.bank = bank.id)
WHERE (error is false)
I expect an output such as:
payment_id amount type flag
1 81 3 NULL
2 104 2 1
3 150 2 1
4 234 1 1
However, I'm only getting the first record such as:
payment_id amount type flag
2 104 2 1
I tried your table structure in my local and it is working perfectly.
I need one thing from you is in which table you are having error column.
If I comment where condition then it is working fine.
If you're getting fewer rows than you expect, it's either due to:
Join condition
You're doing a INNER joins to the customers and bank tables. If you have 4 source rows in your trans table, but only one row that matches in your customers table (condition user_id = cust_id), then you will only have one row returned.
The same goes for the subsequent join to your bank table. If there you somehow have a transaction that references a bank which is not defined in the bank table, then you won't see a record for this row.
WHERE clause
Obviously you won't see any rows that don't meet the conditions specified here.
It's probably #1 -- check to see if the rows with payment_id IN (1,3,4) have corresponding user id values in the user table and corresponding bank id values in the banks table.

MySQL - SQL select query with two tables using where, count and having

There are two tables: client and contract.
client table:
client_code INT pk
status VARCHAR
A client can have 1 or more contracts. The client has a status column which specifies if it has valid contracts - the values are 'active' or 'inactive'. The contract is specified for a client with active status.
contract table:
contract_code INT pk
client_code INT pk
end_date DATE
A contract has an end date. A contract end date before today is an expired contract.
REQUIREMENT: A report requires all active clients with contracts, but with all (not some) contracts having expired date. Some example data is shown below:
Client data:
client_code status
----------------------------------
1 active
2 inactive
3 active
4 active
Contract data:
contract_code client_code end_date
-------------------------------------------------------------
11 1 08-12-2018
12 1 09-12-2018
13 1 10-12-2018
31 3 11-31-2018
32 3 10-30-2018
41 4 01-31-2019
42 4 12-31-2018
Expected result:
client_code
-------------
1
RESULT: This client (client_code = 1) has all contracts with expired dates: 08-12-2018, 09-12-2018 and 10-12-2018.
I need some help to write a SQL query to get this result. I am not sure what constructs I have to use - one can point out what I can try. The database is MySQL 5.5.
One approach uses aggregation. We can join together the client and contract tables, then aggregate by client, checking that, for an active client, there exist no contract end dates which occur in the future.
SELECT
c.client_code
FROM client c
INNER JOIN contract co
ON c.client_code = co.client_code
WHERE
c.status = 'active'
GROUP BY
c.client_code
HAVING
SUM(CASE WHEN co.end_date > CURDATE() THEN 1 ELSE 0 END) = 0;
Demo
Note: I am assuming that your dates are appearing in M-D-Y format simply due to the particular formatting, and that end_date is actually a proper date column. If instead you are storing your dates as text, then we might have to make a call to STR_TO_DATE to convert them to dates first.
Is that what you're looking for?
select clients.client_code
from clients
join contracts
on contracts.client_code=clients.client_code
where status='active'
group by clients.client_code
having min(end_date)>curdate()

Trying to retrieve records with data in one column that doesn't match data from another column

So I have a table of records in Access (example below), where I want to retrieve the records where an Entry Date occurs on a date that a Transaction Date that does not occur for a given person. There also may days that a transaction may occur, but there is no Entry Date. I am only concerned here with the rows that have an Entry Date/Time.
Transaction Date/Time First Name Last Name Entry Date/Time
07/02/2014 11:45 PM Sally Smith 07/14/2014 12:17 PM
07/02/2014 07:34 AM John Foobar 07/02/2014 01:34 PM
07/03/2014 08:56 AM Sally Smith 07/02/2014 08:00 AM
07/03/2015 09:33 AM John Foobar
What I would be interested in retrieving here is the first transaction for Sally Smith, because its Entry Date occurs on a day that Sally Smith had no Transactions.
I am trying to build this utilizing a Query where the data is retrieved from SQL.
Thanks!
You could use a sub query that checks whether there's no record having an entry date that matches a transaction date.
Use the Format function to check on the date part only.
PS I'd include a PersonID primary key as the combination of first and last name is not unique.
Originally, in the sub query FORMAT(b.[Entry Date/Time],'dd-mm-yyyy') and Format(a.[Transaction Date/Time],'dd-mm-yyyy') were used.
I made an error while copy and pasting.
Entry Date should refer to table alias a and Transaction Date should refer to table alias b.
I adjusted the original query.
SELECT a.[Transaction Date/Time], a.[First Name], a.[Last Name], a.[Entry Date/Time]
FROM yourtable a
WHERE a.[Entry Date/Time] IS NOT NULL
AND NOT EXISTS
(
SELECT '1'
FROM yourtable AS b
WHERE FORMAT(a.[Entry Date/Time],'dd-mm-yyyy') = Format(b.[Transaction Date/Time],'dd-mm-yyyy')
AND b.[First Name] = a.[First Name]
AND b.[Last Name] = a.[Last Name]
)

How to create a trigger on table to update field after one hour if a specific value have been set

My database stores the parking status information 1
The status field has three values (0 for empty, 1 for occupied and 2 for waiting)
If the parking status remains 2 for 1 hour I want to set it to 0 and set the username field to null.
Is there any way to do it with triggers.
You probably looking to create a Event like
CREATE EVENT myevent
ON SCHEDULE EVERY HOUR
DO
UPDATE mytable
SET status = 0, username = null
where status = 2;

How can I find the correct prior status row in this table with a SQL query?

Imagine a workflow for data entry. Some forms come in, they are typed into a system, reviewed, and hopefully approved. However, they can be rejected by a manager and will have to be entered again.
So, an ideal workflow would go like this:
recieved > entered > approved
But this COULD happen:
received > entered > rejected > entered > rejected > approved
At each stage, we record who updated the form to its current status - who entered it, who rejected it, or who approved it. So the forms status table looks like this:
form_id status updated_by updated_at
1 received Bob (timestamp)
1 entered Bob (timestamp)
1 approved Susan (timestamp)
2 received Bob (timestamp)
2 entered Bob (timestamp)
2 rejected Susan (timestamp)
2 entered Carla (timestamp)
2 rejected Susan (timestamp)
2 entered Sam (timestamp)
2 approved Susan (timestamp)
Here's what I'm trying to do: write a rejection report. I want a row for each rejection, and joined to that row, I want to see who did the work that got rejected.
As a human, I can see that, for a given status row with status 'rejected', the row that will tell me who did the faulty work will be the one that
shares the same form_id and
has a prior timestamp closest to the rejection.
But I'm having trouble telling MySQL that.
Can anybody see how to construct this query?
A subselect ended up working for me.
SELECT
`s1`.`form_id`,
(
SELECT
`s2`.`updated_by`
FROM
statuses s2
WHERE
`s2`.`form_id` = `s1`.`form_id`
AND
`s2`.`updated_at` < `s1`.`updated_at`
ORDER BY
`s2`.`updated_at` DESC
LIMIT 1
) AS 'made_rejected_change'
FROM
statuses s1
WHERE
`s1`.`status` = 'rejected'
Another solution that uses subselect (this time not a correlated subquery):
SELECT
w1.*,
w2.entered_by
FROM (
SELECT
wr.form_id,
wr.updated_at AS rejected_at,
wr.updated_by AS rejected_by,
MAX(we.updated_at) AS entered at
FROM workflow wr
INNER JOIN workflow we ON we.status = 'entered'
AND wr.form_id = we.form_id
AND wr.updated_at > we.updated_at
WHERE wr.status = 'rejected'
GROUP BY
wr.form_id,
wr.updated_at,
wr.updated_by
) w1
INNER JOIN workflow w2 ON w1.form_id = w2.form_id
AND w1.entered_at = w2.updated_at
The subselect lists all the rejecters and the immediately preceding entered timestamps. Then the table is joined once again to extract the names corresponding to the entered_at timestamps.
You want to get the rejected timestamp and then figure out the entry that appeared right before it based on the timestamp. I'm assuming that timestamp actually holds a date/time and isn't an SQL server timestamp field (completely different).
declare #rejectedTimestamp timestamp
select #rejectedTimestamp = timestamp
from table
where status = 'rejected'
select top 1 *
from table
where timestamp < #rejectedtimestamp
order by timestamp desc