How can I check multiple line for one customer with SQL? - sql

I have a table like this:
id | START_DATE | END_DATE | id_customer
----------------------------------------
1 | 01/05/2016 | 31/05/2016 | 1234
2 | 10/10/2016 | 11/11/2016 | 1234
3 | 11/11/2016 | 15/05/2017 | 1234
4 | 31/12/2016 | 31/06/2017 | 1234
I want select if a START_DATE equal a END_DATE.
For example:
11/11/2016 line id 3 don't equal 31/05/2016 line id 1
11/11/2016 line id 3 equal 11/11/2016 line id 2
11/11/2016 line id 3 don't equal 15/05/2017 line id 3
11/11/2016 line id 3 don't equal 31/06/2017 line id 4
I have try a request like this
SELECT id_cutsomer,START_DATE, END_DATE
FROM TABLE
WHERE START_DATE IN (
SELECT END_DATE FROM DATA_BEAUTY_BOX
)
I want this result:
START_DATE | END_DATE | id_customer
------------------------------------
11/11/2016 | 11/11/2016 | 1234
Can you help me ?
Thanks in advance

I think a self join should suffice
select t1.START_DATE, t2.END_DATE, t1.ID_CUSTOMER
from yourTable t1
join yourTable t2
on t1.START_DATE = t2.END_DATE
If you don't want to mix dates of different customers, you will have to make the join condition stricter
select t1.START_DATE, t2.END_DATE, t1.ID_CUSTOMER
from yourTable t1
join yourTable t2
on t1.START_DATE = t2.END_DATE and
t1.ID_CUSTOMER = t2.ID_CUSTOMER

I would join the tables on Customer ID and then Add the (Start Date = End Date) condition on the WHERE clause. (although you could do them both on the JOIN)
SELECT t1.START_DATE, t2.END_Date, t1.id_customer
FROM MyTable t1
INNER JOIN MyTable t2
ON t1.id_customer = t2.id_customer
WHERE t1.START_DATE = t2.END_Date

Related

Tie-breaking mutliple matches on MAX() in SQL

I have a table that looks like this:
| client_id | program_id | provider_id | date_of_service | data_entry_date | data_entry_time |
| --------- | ---------- | ----------- | --------------- | --------------- | --------------- |
| 2 | 5 | 6 | 02/02/2022 | 02/02/2022 | 0945 |
| 2 | 5 | 6 | 02/02/2022 | 02/07/2022 | 0900 |
| 2 | 5 | 6 | 02/04/2022 | 02/04/2022 | 1000 |
| 2 | 5 | 6 | 02/04/2022 | 02/04/2022 | 1700 |
| 2 | 5 | 6 | 02/04/2022 | 02/05/2022 | 0800 |
| 2 | 5 | 6 | 02/04/2022 | 02/05/2022 | 0900 |
I need to get the most recent date_of_service entered. From the table above, the desired result/row is:
date_of_service = 02/04/2022, data_entry_date = 02/05/2022, data_entry_time = 0900
This resulting date_of_service will be left joined to the master table.
This query mostly works:
SELECT t1.client_id, t1.program_id, t1.provider_id, t2.date_of_service
FROM table1 as t1
WHERE provider_id = '6'
LEFT JOIN
(SELECT client_id, program_id, provider_id, date_of_service
FROM table2) as t2
ON t2.client_id = t1.client_id
AND t2.program_id = t1.program_id
AND t2.provider_id = t1.provider_id
AND t2.date_of_service =
(SELECT MAX(date_of_service)
FROM t2 as t3
WHERE t3.client_id = t1.client_id
AND t3.program_id = t1.program_id
AND t3.provider_id = t1.provider_id
)
)
But it also returns multiple rows whenever there is more than one match on the max(date_of_service).
To solve this, I need to use the max data_entry_date to break any ties whenever there is more than one row that matches the max(date_of_service). Likewise, I also need to use the max data_entry_time to break any ties whenever there is more than one row that also matches the max data_entry_date.
I tried the following:
SELECT t1.client_id, t1.program_id, t1.provider_id, t2.date_of_service
FROM table1 as t1
WHERE provider_id = '6'
LEFT JOIN
(SELECT TOP(1) client_id, program_id, provider_id, date_of_service, data_entry_date, data_entry_time
FROM table2
ORDER BY date_of_service DESC, data_entry_date DESC, data_entry_time DESC
) as t2
ON t2.client_id = t1.client_id
AND t2.program_id = t1.program_id
AND t2.provider_id = t1.provider_id
But I can only get it to return null values for the date_of_service.
Likewise, this:
SELECT t1.client_id, t1.program_id, t1.provider_id, t2.date_of_service
FROM table1 as t1
WHERE provider_id = '6'
LEFT JOIN
(
SELECT TOP(1) client_id AS client_id2, program_id AS program_id2, provider_id AS provider_id2, date_of_service, data_entry_date, data_entry_time
FROM table2 AS t3
JOIN
(SELECT
MAX(date_of_service) AS max_date_of_service
,MAX(data_entry_date) AS max_data_entry_date
FROM table1
WHERE date_of_service = (SELECT MAX(date_of_service) FROM table2)
) AS t4
ON t3.date_of_service = t4.max_date_of_service
AND t3.data_entry_date = t4.max_data_entry_date
ORDER BY data_entry_time
) AS t2
ON t2.client_id2 = t1.client_id
AND t2.program_id2 = t1.program_id
AND t2.provider_id2 = t1.provider_id
... works (meaning it doesn't throw any errors), but it only seems to return null values for me.
I've tried various combinations of MAX, ORDER BY, and multiple variations of JOIN's, but haven't found one that works yet.
I don't know what version my SQL database is, but it doesn't appear to handle window functions like OVER and PARTITION or other things like COALESCE. I've been using DBeaver 22.2.0 to test the SQL scripts.
Based on your what you've provided, looks like you can simply query table2:
SELECT client_id, program_id, provider_id, MAX(date_of_service), MAX(data_entry_date), MAX(data_entry_time)
FROM table2
GROUP BY client_id, program_id, provider_id
If you need to join this result set to table1, just JOIN to the statement above on client_id, program_id, provider_id
Try using below query. This is using just joins and sub query.
SELECT TOP 1 * FROM table1 t1
JOIN (
SELECT
MAX(date_of_Service) AS Max_date_of_Service
,MAX(data_entry_date) AS Max_data_entry_date
FROM table1
WHERE date_of_Service = (SELECT MAX(date_of_Service) FROM table1)
)t2
ON t1.date_of_Service = t2.Max_date_of_Service
AND t1.data_entry_date = t2.Max_data_entry_date
ORDER BY data_entry_time

Joining rows from two tables

I have two tables Table1 and Table2. I wanted to join the two tables data based on the TIME_STAMP data field
I have tried the below query but I am not able to get the expected result
Table 1
CATEGORY_ID ID TIME_STAMP VALUE
-------------------------------------
1 444 30-Mar-17 XXX
1 444 31-Jul-18 YYY
1 444 15-Jan-19 ZZZ
Table 2
CATEGORY_ID ID TIME_STAMP VALUE
------------------------------------------
2 444 30-Mar-17 10/31/2017
2 444 30-May-18 10/25/2018
2 444 13-Jun-19 10/25/2018
Actual Result:
TIME_STAMP Table 1 VALUE Table 2 value
-------------------------------------------
30-Mar-17 XXX 10/31/2017
31-Jul-18 YYY NULL
15-Jan-19 ZZZ NULL
Query :
SELECT
T1.TIME_STAMP ,
T1.X_VALUE,
T2.X_VALUE
FROM
TABLE1 T1
LEFT OUTER JOIN TABLE2 T2 ON T1.ID = T2.ID
AND
TO_CHAR(T1.TIME_STAMP,'MM/DD/YYYY')
=TO_CHAR(T2.TIME_STAMP,'MM/DD/YYYY')
AND
T2.CATEGORY_ID=2
WHERE
T1.CATEGORY_ID =1 AND T1.ID= 444
Expected Result:
TIME_STAMP Table1 VALUE Table2 VALUE
-----------------------------------------
30-Mar-17 XXX 10/31/2017
30-May-18 NULL 10/25/2018
31-Jul-18 YYY NULL
15-Jan-19 ZZZ NULL
13-Jun-19 NULL 10/25/2018
FULL OUTER JOIN with filtering is tricky. I recommend using a subquery for the filtering criteria:
select coalesce(t1.time_stamp, t2.time_stamp) as time_stamp,
t1.x_value, t2.x_value
from (select t1.*
from table1 t1
where t1.CATEGORY_ID = 1 and T1.ID = 444
) t1 full join
(select t2.*
from table2 t2
where t2.id = 444 and t2.category_id = 2
) t2
on t2.id = t1.id and
trunc(t2.time_stamp) = trunc(t1.time_stamp);
Based on your expected result I think you want to do a FULL OUTER JOIN on the TIME_STAMP column.
You could do something like this.
SELECT COALESCE(t1.time_stamp, t2.time_stamp) AS TIME_STAMP,
t1.value as T1_value,
t2.value as T2_value
FROM table01 t1
FULL OUTER JOIN table02 t2 ON t1.time_stamp = t2.time_stamp
+-------------+-----------+------------+
| TIME_STAMP | T1_value | T2_value |
+-------------+-----------+------------+
| 2017-03-30 | XXX | 10/31/2017 |
| 2018-07-31 | YYY | (null) |
| 2019-01-15 | ZZZ | (null) |
| 2018-05-30 | (null) | 10/25/2018 |
| 2019-06-13 | (null) | 10/25/2018 |
+-------------+-----------+------------+
Note: I have used SQL Server since you haven't mentioned a DBMS.
before you join the two tables with timestamp, you need trunc the timestamp to Date.
like TRUNC("TimeStamp", DATE)
SELECT COALESCE(t1.time_stamp, t2.time_stamp) AS TIME_STAMP,
t1.value as T1_value,
t2.value as T2_value
FROM table01 t1
FULL OUTER JOIN table02 t2
ON trunc(t1.time_stamp, 'DATE') = trunc(t2.time_stamp, 'DATE');

Update fields with an ID that is driven by date range

I have two tables in SQL:
T1 is laid out as follows:
PrID NapID URN Date
-------------------------------------------
12345 | NULL | 123 | 2019-06-02
23456 | NULL | 456 | 2019-07-03
34567 | NULL | 789 | 2019-07-05
T2 is laid out as follows:
SYSApID PnID StartDate EndDate
-------------------------------------------
54321 | 2 | 2019-06-01 | 2019-06-30
65432 | 3 | 2019-07-01 | 2019-07-31
I'm hoping for a pointer as to how to update the column NapID in table 1, with with the SYSApID from table 2, where it will apply the relevant ID based on where the Date in table 1 falls between the StartDate and EndDate in table2.
a mixture of previous answers
UPDATE
t1
SET
NapID = t2.SYSApID
FROM
t1
JOIN t2 ON t1.date between t2.StartDate and t2.EndDate
You didn't specify your DBMS, so this answer is for SQL SERVER.
update t1
set t1.napID = (select top 1 t2.SYSApID from table2 t2 where t1.[Date] between t2.StartDate and t2.EndDate)
from table1 t1
Try this:
UPDATE t1
SET
t1.napid = t2.sysapid
FROM t1
JOIN t2 ON t2.startdate = CONVERT(VARCHAR(10), DATEADD(month, DATEDIFF(month, 0, date), 0), 120)
You can try below, this works in Oracle :-
update t1
set t1.napID = (select t2.sysappid from t2 where t1.date between t2.start_date and t2.End_date and rownum <2);

DB2 JOIN, UNION, and pull max value from each group

I am having a difficult time wrapping my head around the path for solving a problem in DB2. I have three tables that look like this...
PARENT
id | label
--------------
1 | One
2 | Two
3 | Three
TABLE1
id | parentid | eventdate
-------------------------
1 | 1 | 2015-11-01
2 | 1 | 2015-12-01
3 | 2 | 2015-10-01
4 | 2 | 2015-09-01
5 | 3 | 2015-08-01
6 | 3 | 2015-07-01
TABLE2
id | parentid | eventdate
-------------------------
1 | 1 | 2015-11-15
2 | 1 | 2015-12-15
3 | 2 | 2015-07-15
4 | 2 | 2015-09-15
5 | 3 | 2015-08-15
6 | 3 | 2015-05-15
Ultimately, I need to find the max date from either table for each parent id. My thought is to UNION two SELECTs, each being JOINed to PARENT, but I am at a complete loss as to how to only pull back a single row for each parent that consists of the max date from either TABLE1 or TABLE2 like this:
One: 2015-12-15
Two: 2015-10-01
Three: 2015-08-15
If anyone could offer some guidance I would be extremely grateful.
You are on the right track. Use a union in a subquery and then join PARENT and GROUP BY label to get the MAX date.
SELECT label, MAX(eventdate) AS maxeventdate FROM (
SELECT parentid, eventdate FROM TABLE1
UNION ALL
SELECT parentid, eventdate FROM TABLE2)
JOIN PARENT ON (id = parentid)
GROUP BY label
SELECT label,
CASE WHEN max(t1.eventdate) > max(t2.eventdate)
THEN max(t1.eventdate)
ELSE max(t2.eventdate)
END as eventdate
FROM PARENT p
JOIN TABLE1 t1
ON p.id = t1.id
JOIN TABLE2 t2
ON p.id = t2.id
GROUP BY p.label
One method is to use union all followed by aggregation. The following does this with a twist, which is to pre-aggregate the results on each table:
select p.label, max(maxed) as max_eventdate
from ((select parentid, max(eventdate) as maxed
from table1
group by parentid
) union all
(select parentid, max(eventdate)
from table2
group by parentid
)
) t12 join
parent p
on t12.parentid = p.id
group by p.label;
There's a function GREATEST() just for this purpose, so you can adjust the solution proposed by #JuanCarlosOropeza:
SELECT label, GREATEST(max(t1.eventdate), max(t2.eventdate)) eventdate
FROM PARENT p
JOIN TABLE1 t1 ON p.id = t1.id
JOIN TABLE2 t2 ON ON p.id = t2.id
GROUP BY p.label
You may want to use LEFT JOIN in case events may be present only in one of the two event tables.

Getting all the current effective records from a ORACLE table

I have two tables in oracle database
Table 1 say table1 with fields (id, name)
Records e.g.
###############
id | name
1 | Chair
2 | Table
3 | Bed
###############
and Table 2 say table2 with fields (id, table1_id, date, price)
##############################
id |table1_id| date | price
1 | 1 | 2013-09-09 | 500
2 | 1 | 2013-08-09 | 300
3 | 2 | 2013-09-09 | 5100
4 | 2 | 2013-08-09 | 5000
5 | 3 | 2013-09-09 | 10500
################################
What I want to achieve is to retrieve all the latest price of items from table 2
Result of SQL should be like
##############################
id |table1_id| date | price
1 | 1 | 2013-09-09 | 500
3 | 2 | 2013-09-09 | 5100
5 | 3 | 2013-09-09 | 10500
################################
I am able to run in mysql by following query
SELECT t2.id, t1.id, t1.name, t2.date, t2.price
FROM table1 t1 JOIN table2 t2
ON (t1.id = t2.table1_id
AND t2.id = (
SELECT id
FROM table2
WHERE table1_id = t1.id
ORDER BY table2.date DESC
LIMIT 1
));
but it's not working in ORACLE, Here i Need a query which can run on both server with minor modification
You may try this (shoud work in both MySQL and Oracle):
select t2.id, t2.table1_id, t2.dat, t2.price
from table1 t1 join table2 t2 on (t1.id = t2.table1_id)
join (select table1_id, max(dat) max_date
from table2 group by table1_id) tmax
on (tmax.table1_id = t2.table1_id and tmax.max_date = t2.dat);
This query may return several rows for the same table1_id and date if there are several prices in table2, like this:
##############################
id |table1_id| date | price
1 | 1 | 2013-09-09 | 500
2 | 1 | 2013-09-09 | 300
It's possible to change the query to retrieve only 1 row for each table1_id, but there should be some additional requirements (which row to choose in the above example)
if it doesn't matter then you may try this:
select max(t2.id) as id, t2.table1_id, t2.dat, max(t2.price) as price
from table1 t1 join table2 t2 on (t1.id = t2.table1_id)
join (select table1_id, max(dat) max_date
from table2 group by table1_id) tmax
on (tmax.table1_id = t2.table1_id and tmax.max_date = t2.dat)
group by t2.table1_id, t2.dat;
You can try this using GROUP BY instead, since you're not retrieving the product name from table1 except the product id (which is already in table2)
SELECT id,table1_id,max(date),price
FROM table2
GROUP BY id,table1_id,price
this is what you want :
select t2.id,t2.table1_id,t1.name,t2.pricedate,t2.price
from table1 t1
join
(
select id,table1_id, pricedate,price, row_number() over (partition by table1_id order by pricedate desc) rn
from table2
) t2
on t1.id = t2.table1_id
where t2.rn = 1