I have a table that have multiple comments in one field.
For eg,
1) CLAIM REFILED Rebecca Byrd 1/17/2018 3:17:53 PM PER CHGS, WE NEED
TO REFILE THIS CLAIM Rebecca Byrd 1/10/2018 1:55:37 PM WAITING ON HOME
PLAN TO REPLY Rebecca Byrd 1/2/2018 1:58:31 PM A/R SENT TO CHGS ON
THIS CLAIM. DENIED AS A DUPLICATE, BUT THERE WAS ONLY ONE CLAIM IN
ILINKBLUE FOR THIS DOS. Test Byrd 12/29/2017 6:34:36 AM
2) HCRR ACCOUNT Sheila Johnson 9/28/2017 7:37:55 AM
3) Contacted VA VISN spoke with Mary she stated pmt $18.32 was made on
06/27/2014 - #675678- she gave me treasury uh# 86-72-1141. I
contacted TEST and spoke with TEST - i gave her number, date and pmt -
she found ck and pmt of $0.00 for date 06/27/2014- she said it was
cashed under blah bank - trace #0jgdjgkd. Test Test 7/28/2017 1:21:11
PM
And I want to split it into different rows like this
1) CLAIM REFILED Rebecca Byrd 1/17/2018 3:17:53 PM
2) PER BCBS, WE NEED TO REFILE THIS CLAIM Rebecca Byrd 1/10/2018 1:55:37 PM
3) WAITING ON HOME PLAN TO REPLY Rebecca Byrd 1/2/2018 1:58:31 PM
4) A/R SENT TO BCBS ON THIS CLAIM. DENIED AS A DUPLICATE, BUT THERE WAS ONLY ONE CLAIM IN ILINKBLUE FOR THIS DOS. Rebecca Byrd 12/29/2017 6:34:36 AM
All the comments will end with a date. So I will thinking I can use AM or PM as a separator. But Having difficulty separating it.
First of all: This design is very bad and you should - if there is any chance -
really change this! Use this approach to transfer all comments into a related side table.
Your question is not very clear, but my magic crystal ball was in a good mood and telling me, that you might be looking for this:
CREATE FUNCTION dbo.SplitCommentOnTime(#str VARCHAR(MAX))
RETURNS TABLE
AS
RETURN
WITH recCTE AS
(
SELECT 1 AS Pos
,LEFT(#str,PATINDEX('%:[0-5][0-9] [AP]M %',#str + ' ')+5) AS Part
,SUBSTRING(#str,PATINDEX('%:[0-5][0-9] [AP]M %',#str + ' ')+7,LEN(#str)) AS Remainder
UNION ALL
SELECT Pos+1
,LEFT(Remainder,PATINDEX('%:[0-5][0-9] [AP]M %',Remainder + ' ')+5)
,SUBSTRING(Remainder,PATINDEX('%:[0-5][0-9] [AP]M %',Remainder + ' ')+7,LEN(#str))
FROM recCTE
WHERE PATINDEX('%:[0-5][0-9] [AP]M %',Remainder + ' ')>0
)
SELECT Pos,Part
FROM recCTE;
GO
DECLARE #tbl TABLE(ID INT IDENTITY,Comment VARCHAR(MAX));
INSERT INTO #tbl VALUES
('CLAIM REFILED Rebecca Byrd 1/17/2018 3:17:53 PM PER CHGS, WE NEED TO REFILE THIS CLAIM Rebecca Byrd 1/10/2018 1:55:37 PM WAITING ON HOME PLAN TO REPLY Rebecca Byrd 1/2/2018 1:58:31 PM A/R SENT TO CHGS ON THIS CLAIM. DENIED AS A DUPLICATE, BUT THERE WAS ONLY ONE CLAIM IN ILINKBLUE FOR THIS DOS. Test Byrd 12/29/2017 6:34:36 AM')
,('HCRR ACCOUNT Sheila Johnson 9/28/2017 7:37:55 AM')
,('Contacted VA VISN spoke with Mary she stated pmt $18.32 was made on 06/27/2014 - #675678- she gave me treasury uh# 86-72-1141. I contacted TEST and spoke with TEST - i gave her number, date and pmt - she found ck and pmt of $0.00 for date 06/27/2014- she said it was cashed under blah bank - trace #0jgdjgkd. Test Test 7/28/2017 1:21:11 PM')
SELECT *
FROM #tbl
OUTER APPLY dbo.SplitCommentOnTime(Comment);
GO
DROP FUNCTION dbo.SplitCommentOnTime;
The result
ID Pos Part
1 1 CLAIM REFILED Rebecca Byrd 1/17/2018 3:17:53 PM
1 2 PER CHGS, WE NEED TO REFILE THIS CLAIM Rebecca Byrd 1/10/2018 1:55:37 PM
1 3 WAITING ON HOME PLAN TO REPLY Rebecca Byrd 1/2/2018 1:58:31 PM
1 4 A/R SENT TO CHGS ON THIS CLAIM. DENIED AS A DUPLICATE, BUT THERE WAS ONLY ONE CLAIM IN ILINKBLUE FOR THIS DOS. Test Byrd 12/29/2017 6:34:36 AM
2 1 HCRR ACCOUNT Sheila Johnson 9/28/2017 7:37:55 AM
3 1 Contacted VA VISN spoke with Mary she stated pmt $18.32 was made on 06/27/2014 - #675678- she gave me treasury uh# 86-72-1141. I contacted TEST and spoke with TEST - i gave her number, date and pmt - she found ck and pmt of $0.00 for date 06/27/2014- she said it was cashed under blah bank - trace #0jgdjgkd. Test Test 7/28/2017 1:21:11 PM
Some explanation
The function uses a recursive CTE jumping through your strings looking for a pattern. the pattern is %:[0-5][0-9] [AP]M %. That means: a double point, followed by one digit out of 0-5, then a digit 0-9, a blank, either A or P and then an M and a blank.
The rest is LEFT and SUBSTRING
Hint
After having split these string monsters you might use REVERT() and search for the the third blank. Take this fragment, again reverted, and convert it to a real DATETIME. This way you'd get a side table with a good query performance.
You might get the commenter out of this the same way...
Related
For my specific case, n = 4, but may one day need to be n=5 or n=6.
Top level description of what I need: I have a form which allows me to add names and dates to a jump log. I need to build a query that will display the four most recent jumps for each jumper, with a column for each date.
My form stores the data in the "JUMP" table which has 3 fields: JUMPID, NAME, DATE. Sample data looks like this:
JUMPID NAME DATE
1 Joe 01-Jul-16
2 Joe 15-Jul-16
3 Adam 15-Jul-16
4 Joe 26-Jul-16
5 Ryan 28-Jul-16
6 Adam 02-Aug-16
7 Joe 10-Aug-16
8 Adam 10-Aug-16
9 Joe 12-Aug-16
10 Mike 19-Aug-16
11 Joe 19-Aug-16
12 Mike 19-Aug-16
13 Dave 19-Aug-16
14 Ryan 23-Aug-16
The query I am using now returns the 4 most recent jumps for each jumper, but stores all of the dates in the same column. The query is:
Select NAME, [DATE]
From [JUMP]
Where DATE In
(Select Top 4 [DATE]
From [JUMP] jum
Where [JUMP].[NAME] = jum.[NAME]
Order By jum.[DATE] DESC;)
Order By NAME, [DATE] DESC;
The output from this query is displayed like this:
NAME DATE
Adam 10-Aug-16
Adam 02-Aug-16
Adam 15-Jul-16
Dave 19-Aug-16
Joe 19-Aug-16
Joe 12-Aug-16
Joe 10-Aug-16
Joe 26-Jul-16
Mike 19-Aug-16
Mike 19-Aug-16
Ryan 23-Aug-16
Ryan 28-Jul-16
What I want is for these 4 most recent jumps to each have their own column, like this:
NAME RECENT1 RECENT2 RECENT3 RECENT4
Adam 10-Aug-16 02-Aug-16 15-Jul-16
Dave 19-Aug-16
Joe 19-Aug-16 12-Aug-16 10-Aug-16 26-Jul-16
Mike 19-Aug-16 19-Aug-16
Ryan 23-Aug-16 28-Jul-16
Duplicate dates are fine, as the same jumper may jump more than once in a day. Empty, or null, fields are fine for dates for jumpers that have fewer than 4 jumps.
I've gotten halfway there through the use of google which helped me build the query found above. Any help in reaching my preferred end state would be very much appreciated.
I spent several hours trying to solve my problem using the TRANSFORM...PIVOT method in MS Access as suggested by Serg with no success. I think this was mainly due to lacking an additional field that would classify each jump as recent 1, 2, 3, 4, or no longer tracking. I can't think of a way in which this would be done without updating this field for each jumper's records every time they jump. I may be wrong in this, I'm not sure, because again, I'm no expert. If there is a way to assign a value of 1, 2, 3, 4 to each jump that my original query returned as a calculated field (?), I'd be in business with the TRANSFORM method.
That said, I did find a solution that mostly works, but is clunky, in my opinion. I say mostly because it breaks if a jumper jumps more than once in a day. My partial solution involved creating 4 separate queries to identify the first, second, third, and fourth most recent jumps, respectively, and then combining those 4 queries into a final query.
The four queries look like this:
Select NAME, DATE
From JUMP As jum
Where (
Select Count(NAME)
From JUMP
Where NAME = jum.NAME
AND DATE > jum.DATE) = 0; (0 gives me most recent, 1 second most recent, etc.)
Credit for this query goes to Charles Bretana on this stackoverflow question. I don't really understand how it does what it does, but it works for what I need except when there is more than one jump for a jumper.
Using these 4 queries I then constructed another query which combines the 4 into 1. This query looks like this:
SELECT Query1.NAME, Query1.DATE, Query2.DATE, Query3.DATE, Query4.DATE
FROM ((Query2 RIGHT JOIN Query1 ON Query2.NAME=Query1.NAME)
LEFT JOIN Query3 ON Query1.NAME = Query3.NAME)
LEFT JOIN Query4 ON Query1.NAME = Query4.NAME
ORDER BY query1.NAME;
This gives me the data in the format that I need it in: rows with names and 4 columns, one each for 1st/2nd/3rd/4th most recent jumps, but breaks when there is a jumper with more than one jump in a day. Using the original sample data above, the resulting datasheet looks like this:
NAME RECENT1 RECENT2 RECENT3 RECENT4
Adam 10-Aug-16 02-Aug-16 15-Jul-16
Dave 19-Aug-16
Joe 19-Aug-16 12-Aug-16 10-Aug-16 26-Jul-16
Mike 19-Aug-16
Mike 19-Aug-16
Ryan 23-Aug-16 28-Jul-16
If there are more elegant solutions out there, I'd love to see them. Or, if someone knows how to fix the issue I'm having with more than one jump in a day, I'd love some input. Thanks.
I have difficulties formulating my issue.
I have a view which brings these results. There's a need to add a column to the view, which will pair up round-trip flights with identical number.
Flt_No From_Airport To_Airport Dep_Date RequiredResult
124 |LCA |CDG |10/19/14 5:00 1
125 |CDG |LCA |10/19/14 10:00 1
197 |LCA |BCN |10/4/12 5:00 2
198 |BCN |LCA |10/4/12 11:00 2
501 |LCA |HER |15/8/12 12:05 3
502 |HER |LCA |15/8/12 15:15 3
I.e. flight 124 is going from Larnaca to CDG, and flight 125 is going back from CDG to Larnaca - they both have to have the same identifier.
Round-trip flights will always have following flight numbers.
I have a bunch of conditions which I won't write now.
Omitting hours is not an option, they're important.
I was thinking dense_rank() but I don't know how to create one identifier for 2 flights with different numbers, please help.
If your data is similar to the sample data posted, then the following query should give the required result:
SELECT *,
DENSE_RANK() OVER (ORDER BY CASE
WHEN From_Airport < To_Airport THEN From_Airport
ELSE To_Airport
END)
FROM mytable
Join conditions are not limited to simple equality. Assuming {Flight No, Departure, Destination} is unique on any one day, then a self join should do it:
select whatever
from flights outbound
inner join flights inbound on outbound.flt_no+1 = inbound.flt_no
and cast(outbound.dep_date, date)
= cast(inbound.dep_date, date)
and outbound.From_Airport = inbound.To_Airport
and outbound.To_Airpott = inbound.From_Ariport
I'm new here, and new to SQL. I have searched, but I can't seem to find an answer to my question. Maybe you gurus can help. I have a table that has customer ID numbers and their status (number) among other things. For instance, a few lines would be like this:
Status - ACCTnum - CustName - City - State
95 - A330 - Billy Burger - Cleveland - Oh
11 - A330/Q - Billy Burger Store#2 - Cleveland - Oh
15 - B250 - Spanky - Columbus - Oh
15 - B250/Z - Spanky#2 - Springfield - OH
15 - B250/Y - Spanky#3 - Miami - FL
We see here, there is a main account number, and a sub account number, but they occupy the same field. Account A330 is billy burger, and his second store is A330/Q. The status column is for their salesman number. If the number is 95, it is a dead account. The problem is, for our purposes, the status of a main account cannot be dead if a sub account is in good standing. So what I need is a query that can basically select any records that meet the criteria: "If ACCTnum is status 95, and has sub accounts that are not status 95"
Ideally if I ran the query on the table above it should return the first two records, since A330 is status 95 and A330/Q is not. It should ignore the other records.
I have tried the INTERSECT command with no success (I assume because it only works for two different tables?). I am a total SQL n00b, be gentle ;)
select distinct c1.*
from Customers c1
inner join Customers c2 ON c2.ACCTnum LIKE c1.ACCTnum + '%'
where c1.ACCTnum.status = 95 and c2.ACCTnum <> 95
I have 3 tables:
Clients
User_Defined_Definitions
User_Defined_Data
The Clients table has basic information:
ClientID, Name, Address...
The User_Defined_Definitions has the title for the user def fields:
StartDate, SalesRep, Website...
Then the User_Defined_Data table contains the data to fill those fields for each client in the client table.
I've built a query which pulls all the data I need, but it pulls one row for each of the User_Defined_Data rows that exist for that client. What I would like to do is pull one row for each client, and append as many columns as needed to fill all the user defined fields into the one row.
ClientID Name Address Description Data
155555 Calvin 123 Fake St StartDate 10/10/2013
155555 Calvin 123 Fake St SalesRep Tom
155555 Calvin 123 Fake St Website http://www.fakesite.com
155556 Steve 456 Root Rd StartDate 8/5/2013
155557 Kathy 715 Main St StartDate 5/5/2010
155557 Kathy 715 Main St SalesRep Jessica
155557 Kathy 715 Main St Website http://www.fakesite2.com
155558 Jenny 345 Fake St StartDate 9/9/2012
155558 Jenny 345 Fake St Website http://www.fakesite3.com
The first three columns come from the Client table. The Description column comes from the User_Defined_Definitions table. And the Data comes from the User_Defined_Data table.
And I'd like to see it similar to this
ClientID Name Address StartDate SalesRep Website
155555 Calvin 123 Fake St 10/10/2013 Tom http://www.fakesite.com
155556 Steve 456 Root Rd 8/5/2013
155557 Kathy 715 Main St 5/5/2010 Jessica http://www.fakesite2.com
155558 Jenny 345 Fake St 9/9/2012 http://www.fakesite3.com
I know this is possible using sql, but I've just usually written scripts to deal with the data after the export. But this time I need to be able to do it in Access so the table can be re-opened 2 months from now and it will re-query the data in the same way.
Let me know if there's anything else I can provide to help get the right result.
ADDON
I took the long way around and made individual queries for each of the UDF's, then consolidated them all by running a query agains't each to place them all in one line. I am still curious how to do this with SQL though because right now I'm in the midst of changing CRM and Accounting software for my organization, and it's become a daunting task.
Here's the query I was using to pull the UDFs onto separate lines like outlined above.
SELECT dbo_AMGR_Client_Tbl.Client_Id, dbo_AMGR_Client_Tbl.Name,
dbo_AMGR_Client_Tbl.Address_Line_1, dbo_AMGR_Client_Tbl.Address_Line_2,
dbo_AMGR_Client_Tbl.City, dbo_AMGR_Client_Tbl.State_Province,
dbo_AMGR_Client_Tbl.Zip_Code, dbo_AMGR_User_Field_Defs_Tbl.Description,
dbo_AMGR_User_Fields_Tbl.DateCol, dbo_AMGR_User_Fields_Tbl.NumericCol,
dbo_AMGR_User_Fields_Tbl.AlphaNumericCol
FROM dbo_AMGR_User_Field_Defs_Tbl INNER JOIN (dbo_AMGR_Client_Tbl INNER JOIN
dbo_AMGR_User_Fields_Tbl ON dbo_AMGR_Client_Tbl.Client_Id =
dbo_AMGR_User_Fields_Tbl.Client_Id) ON (dbo_AMGR_User_Field_Defs_Tbl.Type_Id =
dbo_AMGR_User_Fields_Tbl.Type_Id) AND (dbo_AMGR_User_Field_Defs_Tbl.Code_Id =
dbo_AMGR_User_Fields_Tbl.Code_Id)
GROUP BY dbo_AMGR_Client_Tbl.Name_Type, dbo_AMGR_Client_Tbl.Client_Id,
dbo_AMGR_Client_Tbl.Name, dbo_AMGR_Client_Tbl.Address_Line_1,
dbo_AMGR_Client_Tbl.Address_Line_2, dbo_AMGR_Client_Tbl.City,
dbo_AMGR_Client_Tbl.State_Province, dbo_AMGR_Client_Tbl.Zip_Code,
dbo_AMGR_User_Field_Defs_Tbl.Description, dbo_AMGR_User_Fields_Tbl.DateCol,
dbo_AMGR_User_Fields_Tbl.NumericCol, dbo_AMGR_User_Fields_Tbl.AlphaNumericCol
HAVING (((dbo_AMGR_Client_Tbl.Name_Type)="C") AND ((dbo_AMGR_Client_Tbl.Name) Not Like "*HOUSE*"))
ORDER BY dbo_AMGR_Client_Tbl.Name;
It seems you have multiple rows related to one clientID in the User_Defined_Data table.
Why don't you rebuild that table so that it contains all the fields you require and is one-to one with Clients?
Otherwise you may use CASE statement in your query and filter its contents by description.
I have the following data in a DB table and would like to find concurrent transactions based on the start and end time.
Patient Start Time End Time
John 08:31A 10:49A
Jim 10:14A 10:30A
Jerry 10:15A 10:28A
Alice 10:18A 12:29P
Bobby 10:32A 10:49A
Sally 10:46A 10:55A
Jane 10:52A 11:29A
Jules 10:54A 11:40A
Adam 10:58A 11:25A
Ben 11:00A 11:20A
Ann 11:31A 11:56A
Chris 11:49A 11:57A
Nick 12:00P 12:21P
Dave 12:00P 12:35P
Steve 12:23P 12:29P
If I want to find any overlapping times with a particular input, how would I write it? For example say I want to find overlaps with the 10:58A-11:25A time. This needs to find potential time concurrencies. I am looking for a count of the maximum number of concurrent overlaps. In my example for 10:58A-11:25A, I would want to see the following (count would be 5):
Patient Start Time End Time
Alice 10:18A 12:29P
Jane 10:52A 11:29A
Jules 10:54A 11:40A
Adam 10:58A 11:25A
Ben 11:00A 11:20A
In my second example some of the concurrent times overlap with the time I am looking for, but they are over before another range start. So, say I am looking for 10:46A-10:55A. I would expect a count of 4. In this example 08:31A-10:49A is dropped because it is over before 10:52A-11:29A starts. Same with 10:32A-10:49A, it was over before 10:52A-11:29A started. So, the most concurrent with the 10:46A-10:55A range would be 4, even though overall there is 6 (2 dropped).
Patient Start Time End Time
Alice 10:18A 12:29P
Sally 10:46A 10:55A
Jane 10:52A 11:29A
Jules 10:54A 11:40A
Can this be done with a sql statement?
The most easy and clean method is to exclude rows:
All rows except:
rows than ends before start time
rows than begins after end time
sample:
select * from your table t
where
not (
t.end < begin_time
or
t.start > end_time
)
Sample in sqlfiddle