Concatenate fields with different data types - sql

I'm trying to concatenate fields with VarChar and Date into one VarChar field for a database of tourdates. So, imagine a table of, say, Madonna tour dates as such:
TourName TourStDt TourEndDt
Like A Virgin 3/5/1985 12/1/1985
Material Girl 1/15/1986 10/10/1987
I'm sure the dates aren't accurate, but whatever... Anyway, so I want to create a query that concatenates the TourName, TourStDt and TourEndDt fields so that it looks like this:
Like A Virgin (3/5/1985 to 12/1/1985)
Material Girl (1/15/1986 to 10/10/1987)
I wrote a query like this:
Select DISTINCT
TourID,
TourName + '(' + TourStDt + ' to ' + TourEndDt + ')' AS TourName2
from [tblTours]
ORDER BY [TourID] ASC
When I do this, I get an error:
The data types nvarchar and date are incompatible in the add operator.
Can anyone tell me how to produce the results I outlined above?

You need to convert the values to strings:
Select DISTINCT TourID,
TourName + '(' + convert(varchar(255), TourStDt) + ' to ' + convert(varchar(255), TourEndDt) + ')' AS TourName2
from [tblTours]
ORDER BY [TourID] ASC ;
I would suggest that you add a third argument to convert() specifying the date format.

Related

SQL Server SELECT To Return String Including Single Quotes

I need to get a formatted string with data from a SELECT statement. The problem is that I need it to return with single quotes. Here's an example.
I have a table that contains 2 columns TrainingSwipeID (int) and ExtendedDate (datetime). For an example I have a row in the table that contains
TrainingSwipeID = 123
TrainingEnd = 04/23/2019 09:00:00
I need to create a SELECT statement that will return the formatted string such as
{'TrainingSwipeID':123,'TrainingEnd ':04/23/2019 09:00:00}
I've researched and found that you can double single quote to get around this issue. I've tried the following with no luck and I get the following error "Conversion failed when converting the varchar value '{'TrainingSwipeID':' to data type int."
SELECT '{''TrainingSwipeID'':' + TrainingSwipeID + '''TrainingEnd'':' + TrainingEnd + '}'
AS MyFormattedString
FROM TrainingSwipe
Can anyone help?
The numeric and date/time data types have a higher precedence than the string data types. That's why you need to convert the numeric types into strings and prevent undesired implicit conversions.
SELECT '{''TrainingSwipeID'':' + CAST(TrainingSwipeID AS varchar(15))
+ '''TrainingEnd'':' + CONVERT( varchar(20), TrainingEnd , 101) + ' '
+ CONVERT( varchar(20), TrainingEnd , 8) + '}'
AS MyFormattedString
FROM TrainingSwipe
I finally used the simplest answer from #AlexKudryashev but Luis' answer worked as well.
SELECT CONCAT('{''TrainingSwipeID'':' , TrainingSwipeID, ',''TrainingEnd'':', TrainingEnd, '}')

Search for specific string inside column field

In my table for specific column values are stored in three diffrent ways as shown below. It could be either one, two or three items separated by commas (of course if more than one value). Minimum is one value, maximum 3 values separated by commas. To be clear i know it's bad approach it was done (not by me) however i have to work on this and i have to change just only this query. Example showing three ways of storing values:
MaterialAttributes (column name)
----------------------------------
1,12,32
3,1
9
I have specific sql query for searching if some value existing within field. It is universal to check all tree ways.
somevalue1
or:
somevalue1,somevalue2
or:
somevalue1,somevalue2,somevalue3
Therefore for instance if i search entire table for each row in that column to get records where somevalue2 appears this query correctly gives me correct result.
This is the query:
";WITH spacesdeleted (vater, matatt) as (SELECT vater, REPLACE(MaterialAttributes, ' ', '') MaterialAttributes FROM myTable),
matattrfiltered (vat) as (SELECT vater FROM spacesdeleted WHERE matatt = #matAttrId
OR matatt LIKE #matAttrId +',%'
OR matatt LIKE '%,'+#matAttrId
OR matatt LIKE '%,'+#matAttrId+',%' ),
dictinctVaters (disc_vats) as (SELECT distinct(vat) FROM matattrfiltered)
SELECT ID from T_Artikel WHERE Vater IN (SELECT disc_vats FROM dictinctVaters)"
Note: For security reasons if for some reasons there are spaces close to commas there will be removed (just information from other developer).
What is the question:
The problem now is that logic changed in the way there could be instead of 3 (max) - 12 to store in that column.
OR matatt LIKE #matAttrId +',%'
OR matatt LIKE #matAttrId +',%'
These are the same, should one be '%,' + #matAttrId?
Regardless, I think there's only 4 cases you need:
= #matAttrId
LIKE #matAttrId + ',%'
LIKE '%,' +#matAttrId
LIKE '%,' +#matAttrId + ',%'
Covering
single value, equals
value is start of list
value is end of list
value is in middle of list
Which is what your original query already has.
You can search with
WHERE ',' + matatt + ',' LIKE '%,' + #matAttrId + ',%'
It works like this: matatt is extended to look like this
,1,12,32,
,3,1,
,9,
Now you can always serach for an id looking like ,id, by using the search pattern %,id,%, where id is the real id.
This works for any number of values per column.

Advanced Sql query to identify missing data

I am currently dealing with a sql server table 'suburb' which has a suburb_id column and an adjacent_suburb_ids column. The adjacent_suburb_ids column is a comma separated string of other suburb_ids.
I have found that some of the records are not reciprocating -
e.g "SuburbA" has "SuburbB" id in adjacent_suburb_ids but "SuburbB" does not have "SuburbA" id in adjacent_suburb_ids
I need to identify all the suburbs which are not reciprocating the adjacent_suburbs, can I do this with a SQL query?
Please do not comment on the data/table structure as it is not in my control and I can't change it.
Assuming I'm understanding your question correctly, you can join the table to itself using the like and not like operators:
select s.suburb_id, s2.suburb_id as s2id
from suburb s
join suburb s2 on
s.suburb_id <> s2.suburb_id
and ',' + s2.adjacent_suburb_ids + ',' like
'%,' + cast(s.suburb_id as varchar(10)) + ',%'
and ',' + s.adjacent_suburb_ids + ',' not like
'%,' + cast(s2.suburb_id as varchar(10)) + ',%'
SQL Fiddle Demo
You need to concatenate the comma before and after to do a search within the set. And yes, if you had the chance, you should consider normalizing the data.

SQL for ordering by number - 1,2,3,4 etc instead of 1,10,11,12

I’m attempting to order by a number column in my database which has values 1-999
When I use
ORDER_BY registration_no ASC
I get….
1
101
102
103
104
105
106
107
108
109
11
110
Etc…
So it appears to be ordering by the first digit as oppose to the number.
Does anyone know what SQL to use if I want to order this by value? So 1,2,3,4,5,6 etc
One way to order by positive integers, when they are stored as varchar, is to order by the length first and then the value:
order by len(registration_no), registration_no
This is particularly useful when the column might contain non-numeric values.
Note: in some databases, the function to get the length of a string might be called length() instead of len().
ORDER_BY cast(registration_no as unsigned) ASC
explicitly converts the value to a number. Another possibility to achieve the same would be
ORDER_BY registration_no + 0 ASC
which will force an implicit conversation.
Actually you should check the table definition and change it. You can change the data type to int like this
ALTER TABLE your_table MODIFY COLUMN registration_no int;
That way indexes can be used properly and the order by won't slow down the query.
If you are using SQL Server:
ORDER_BY cast(registration_no as int) ASC
ORDER_BY cast(registration_no as unsigned) ASC
gives the desired result with warnings.
Hence, better to go for
ORDER_BY registration_no + 0 ASC
for a clean result without any SQL warnings.
I assume your column type is STRING (CHAR, VARCHAR, etc) and sorting procedure is sorting it as a string. What you need to do is to convert value into numeric value. How to do it will depend on SQL system you use.
I prefer doing a "PAD" to the data. MySql calls it LPAD, but you can work your way around to doing the same thing in SQL Server.
ORDER BY REPLACE(STR(ColName, 3), SPACE(1), '0')
This formula will provide leading zeroes based on the Column's length of 3. This functionality is very useful in other situations outside of ORDER BY, so that is why I wanted to provide this option.
Results: 1 becomes 001, and 10 becomes 010, while 100 remains the same.
Sometimes you just don't have a choice about having to store numbers mixed with text. In one of our applications, the web site host we use for our e-commerce site makes filters dynamically out of lists. There is no option to sort by any field but the displayed text. When we wanted filters built off a list that said things like
2" to 8"
9" to 12"
13" to 15" etc, we needed it to sort 2-9-13, not 13-2-9 as it will when reading the numeric values. So I used the SQL Server Replicate function along with the length of the longest number to pad any shorter numbers with a leading space. Now 20 is sorted after 3, and so on.
I was working with a view that gave me the minimum and maximum lengths, widths, etc for the item type and class, and here is an example of how I did the text.
(LBnLow and LBnHigh are the Low and High end of the 5 length brackets.)
REPLICATE(' ', LEN(LB5Low) - LEN(LB1High)) + CONVERT(NVARCHAR(4), LB1High) + '" and Under' AS L1Text,
REPLICATE(' ', LEN(LB5Low) - LEN(LB2Low)) + CONVERT(NVARCHAR(4), LB2Low) + '" to ' + CONVERT(NVARCHAR(4), LB2High) + '"' AS L2Text,
REPLICATE(' ', LEN(LB5Low) - LEN(LB3Low)) + CONVERT(NVARCHAR(4), LB3Low) + '" to ' + CONVERT(NVARCHAR(4), LB3High) + '"' AS L3Text,
REPLICATE(' ', LEN(LB5Low) - LEN(LB4Low)) + CONVERT(NVARCHAR(4), LB4Low) + '" to ' + CONVERT(NVARCHAR(4), LB4High) + '"' AS L4Text,
CONVERT(NVARCHAR(4), LB5Low) + '" and Over' AS L5Text
This problem is just because you have declared the column in CHAR, VARCHAR or TEXT datatype. Just change the datatype to INT, BIGINT etc. This is will solved the problem of your custom ordering.
The easiest way is that datatype of registration_no is INT ;)
order by ´registration_no´ asc will work fine
Output: 1,2,3,4,5....

How to evenly space 3 concatenated fields in the result set

I have three fields that I concatenated into one field, but when I run the query the result-set is correct, but they are not evenly spaced within the one field. How would I space them neatly and correctly. Thank-you for the help.
Here is the query:
SELECT CONVERT(varchar(20),Book)+ Space(2) + '(' + CONVERT(varchar(30),Year)
+ ')' + Space(2) + '(' + CONVERT(varchar(30),Print) + ')' As 'Film Description', Genre,
Cost
FROM Film
Order By Year DESC, Book ASC
Since VARCHAR ignores trailing spaces, you need to use a different data type that doesn't (e.g. CHAR). A few other comments:
be careful about using reserved words such as year and print as column names
be careful about using 'single quotes' as alias delimiters ([square brackets] are more future-proof and harder to muddle with string literals)
you should use the schema prefix (e.g. dbo.Film)
DECLARE #Film TABLE(Book VARCHAR(255), [Year] INT, [Print] VARCHAR(255));
INSERT #Film
SELECT 'a', 2012, 'hello there this is at least 30 characters, right?'
UNION ALL
SELECT 'this must be at least 30 characters too, right?', 2011, 'b';
SELECT CONVERT(CHAR(20), Book)
+ SPACE(2)
+ '(' + CONVERT(CHAR(4),[Year]) + ')'
+ SPACE(2)
+ '(' + CONVERT(CHAR(30), [Print]) + ')'
As [Film Description]
FROM #Film
Order By [Year] DESC, Book;
Use Convert(Char( instead of Convert(Varchar(
Varchars have the spaces stripped off..