How to Split a Column into 2 Columns in SQL - sql

I have an SQL Query which extracts columns from a table that must be in this order
Item Id,
Parms,
Move list,
MsgId. I also have a couple of requirements in the query that must remain there such as UserCode = automation and the Date is set to one day prior to the current day.
An example of the Parms output for one row is such
CURRENT OUTPUT
Parms:
V51370,Move List,M-000001
--
REQUIRED OUTPUT
Media: v51370
Comments: Was Removed From
Move List: M-000001
What I want to do is split this Parms column into two separate columns that are in between the Item Id and Move list Column. The first Column should be called Media which extracts the first six characters from the Parms Column:v51370. The second column is comments and if the MsgId is 1 the comment should be: Was Removed from.
Can Anyone make any suggestions to a possible query I could test? I'm not sure where to fit the Parms column split in there. That would be greatly appreciated.
Please Note: I am using SQL Server Management Studio 2008, and the table name is JnlList.
1 SAMPLE ROW (SELECT * FROM JNLLIST):
ItemId: 2
Date: 20122102.124652563
Object: S-000001
MsgID: 1
Parms: V86143,Scratch List,S-000001
Delimiter: -
UserCode: Automation
ActionId: 5
List Type: S

to seperate the first 6 chars from the parms use
SELECT SUBSTRING(Parms,1,6) AS Media
FROM YOUR TABLE;
Then you can use a subquery with the same syntax to select the rest of the chars from the Parms column and put them into a seperate column

Related

Combine Rows but concatenate on a certain field in Excel Power Query or Microsoft SQL

I have brought a table from an Authority database into Excel via power query OBDC type, that includes fields like:
Date - various
Comments - mem_txt
Sequence - seq_num
The Comments field has a length restriction, and if a longer string is entered, it returns multiple rows with the Comments field being chopped into suitable lengths and the order returned in the Sequence field as per extract below. All other parts of the records are the same.
I want to collapse the rows based and concatenate the various Comments into a single entry. There is a date/time column just outside of the screen shot above that can be used to group the rows by (it is the same for the set of rows, but unique across the data set).
For example:
I did try bring the data in by a query connection, using the GROUP_CONCAT(Comments SEPARATOR ', ') and GROUP BY date, but that command isn't available in Microsoft Query.
Assuming the date/time column you refer to is named date_time, the M code would be:
let
Source = Excel.CurrentWorkbook(){[Name = "Table1"]}[Content],
#"Grouped Rows" = Table.Group(
Source,
{"date_time"},
{{"NewCol", each Text.Combine([mem_text])}}
)
in
#"Grouped Rows"
Amend the Source line as required.

Return Files w/o Note in at least X Days

We have a customer database and I'm trying to get all of the customer files that haven't had a comment on them in three weeks or more.
I'm working with two tables; the file table with info about the file like which staff is assigned to it, and the comments table, where all the comments in the database are. They're linked by the file number field.
If I wanted the file number and date of last note, what SQL should I be using?
I have tried:
SELECT db_file_notes.file_num, Last(db_file_notes.file_date) AS
LastOfnote_date, Last(db_file_notes.note_key) AS LastOfnote_key
FROM db_file_notes
GROUP BY db_file_notes.file_num
ORDER BY db_file_notes.file_num, Last(db_file_notes.note_date);
There are a handful of files that are on the resulting query that shouldn't be. For example, file # 212720's last note was on 7/28, but the above query returns a last note date of 6/26 (the previous last note). Then there's file # 212781 with actual last note on 7/21, but the query is return 6/12 (there five newer notes since the one returned by the query).
There's no date criteria in the above SQL but if I add the <=Date()-21 it's still incorrect (212710 is still there with a last note of 6/26). Interestingly, if I add a filter on the file number to only return a single file number like 212720, the last note date returns correctly.
I've tried sorting by file number then note date, and file number and note key (on the general assumption that newer notes have higher key values) and get the same behavior. Instead of sorting ascending then taking the last record, I've tried sorting descending and taking the first; this returns the correct note for the files affected by the above, but then new cases have the problem but in reverse now.
Sample table:
Without bringing in the second table you could use either of these:
This will return the top grouped date. For example, if your maximum file_date is 12/06/2017 this will return all the records that have a file_date of 12/06/2017.
SELECT TOP 1 file_num
, file_date
, note_key
FROM db_file_notes
WHERE DATEDIFF("d",file_date,DATE())>=21
ORDER BY file_date DESC
This code, on the other hand, will return the maximum date for each group of figures (a group being sets of file_num and note_key)
SELECT file_num
, MAX(file_date) AS Max_File_date
, note_key
FROM db_file_notes
WHERE DATEDIFF("d",file_date,DATE())>=21
GROUP BY file_num, note_key
Note: You don't have to qualify each field name with the table name if the field is unique across all tables (or you're just using one table).

SSRS - How to get column value by column name

I have one table with rows and each row has a column that contains a field name (say raw1 - 'Number001', raw2-'ShortChar003', etc). In order for me to get that value of these fields I have to use a second table; this table has 1 raw with many columns (number001, Number002, ShortChar003, etc).
How can I extract the value?
Good Question..You can use lookup function
=Lookup(Fields!CityColumn.Value, Fields!CityColumn.Value, Fields!CountColumn.Value, "Dataset1")
Or you might have to use string functions..ex LEFT, Substring, Right same like SQL.If possible pls post some data of both tables, I will explain in detail

How to repeat a pattern in an MS Access query

I have a MS Access database and in it are two tables called [Pattern] and [Element].
The following example's show the tables and their respective datatype.
Table 1: [Pattern]
patternID - key
pStart - short date
pEnd - short date
Table 2: [Element]
elementID - key
patternID
text -text(2)
I want to create a query where it will repeat the pattern contained within the text field of the element table. For example
for patternID = 1 there are 4 elementID entries with the text values 1,2,3,4
How do I get a query to repeat 1,2,3,4,1,2,3,4 for as long as the difference between the two dates, pStart and pEnd in the pattern table?
Hopefully this makes sense, thanks in advance. I usually work in Excel so Access is new to me.
You will need a number or factor table with one field with integers from 0 to at least the maximum day count you will have.
Then you can create the first Cartesian query:
Select
patternID
From
Pattern,
Factors
Where
DateAdd("d", [Factor], [pStart]) <= pEnd
Save this as, say, Patterns and create a second Cartesian query:
Select
Element.patternID,
Element.elementID,
Element.Text
From
Patterns,
Element
Where
Patterns.patternID = Element.patternID
Order By
Element.patternID,
Element.elementID,
Element.Text
I'm unsure if you are doing this in the query designer or sql view. If your writing the sql, this might help:
select distinct E.text
from Element E, Pattern P
where E.patternID = P.patternID
AND p.Start <> p.End

Splitting text in SQL Server stored procedure

I'm working with a database, where one of the fields I extract is something like:
1-117 3-134 3-133
Each of these number sets represents a different set of data in another table. Taking 1-117 as an example, 1 = equipment ID, and 117 = equipment settings.
I have another table from which I need to extract data based on the previous field. It has two columns that split equipment ID and settings. Essentially, I need a way to go from the queried column 1-117 and run a query to extract data from another table where 1 and 117 are two separate corresponding columns.
So, is there anyway to split this number to run this query?
Also, how would I split those three numbers (1-117 3-134 3-133) into three different query sets?
The tricky part here is that this column can have any number of sets here (such as 1-117 3-133 or 1-117 3-134 3-133 2-131).
I'm creating these queries in a stored procedure as part of a larger document to display the extracted data.
Thanks for any help.
Since you didn't provide the DB vendor, here's two posts that answer this question for SQL Server and Oracle respectively...
T-SQL: Opposite to string concatenation - how to split string into multiple records
Splitting comma separated string in a PL/SQL stored proc
And if you're using some other DBMS, go search for "splitting text ". I can almost guarantee you're not the first one to ask, and there's answers for every DBMS flavor out there.
As you said the format is constant though, you could also do something simpler using a SUBSTRING function.
EDIT in response to OP comment...
Since you're using SQL Server, and you said that these values are always in a consistent format, you can do something as simple as using SUBSTRING to get each part of the value and assign them to T-SQL variables, where you can then use them to do whatever you want, like using them in the predicate of a query.
Assuming that what you said is true about the format always being #-### (exactly 1 digit, a dash, and 3 digits) this is fairly easy.
WITH EquipmentSettings AS (
SELECT
S.*,
Convert(int, Substring(S.AwfulMultivalue, V.Value * 6 - 5, 1) EquipmentID,
Convert(int, Substring(S.AwfulMultivalue, V.Value * 6 - 3, 3) Settings
FROM
SourceTable S
INNER JOIN master.dbo.spt_values V
ON V.Value BETWEEN 1 AND Len(S.AwfulMultivalue) / 6
WHERE
V.type = 'P'
)
SELECT
E.Whatever,
D.Whatever
FROM
EquipmentSettings E
INNER JOIN DestinationTable D
ON E.EquipmentID = D.EquipmentID
AND E.Settings = D.Settings
In SQL Server 2005+ this query will support 1365 values in the string.
If the length of the digits can vary, then it's a little harder. Let me know.
Incase if the sets does not increase by more than 4 then you can use Parsename to retrieve the result
Declare #Num varchar(20)
Set #Num='1-117 3-134 3-133'
select parsename(replace (#Num,' ','.'),3)
Result :- 1-117
Now again use parsename on the same resultset
Select parsename(replace(parsename(replace (#Num,' ','.'),3),'-','.'),1)
Result :- 117
If the there are more than 4 values then use split functions