Can somebody explain this tricky sql? - sql

what would the below sql return and why?
SELECT 1 + '+' + 2

Same reason SELECT 1 + 'whocares' + 2 results in 3. In some database systems, 'strings' evaluate to 0 if they can't be interpreted as a number. Try SELECT 1 + '2' + 3 to see an example of where it CAN be interpreted as a number.
And yes, the "in some database systems" applies to this whole answer, where I'm going to guess you're using something like MySQL.

One way of thinking about this type of mathematical logic is that SQL manages your math functions in a given order of operation.
SELECT 1 + 'whocares' + 2
-- Results in a number as the first item processed, 1, tells SQL it is about to deal with integers
SELECT 'whocares' + 1 + '...this guy'
-- Results in a string of 'whocares...this guy' as the first item is a string
Actually, the second line may fail depending on which SQL syntax/system you're using... but you get the point.

Related

How to ignore specific string value when using pattern and patindex function in SQL Server Query?

I have this query here.
WITH Cte_Reverse
AS (
SELECT CASE PATINDEX('%[^0-9.- ]%', REVERSE(EmailName))
WHEN 0
THEN REVERSE(EmailName)
ELSE left(REVERSE(EmailName), PATINDEX('%[^0-9.- ]%', REVERSE(EmailName)) - 1)
END AS Platform_Campaign_ID,
EmailName
FROM [Arrakis].[xtemp].[Stage_SendJobs_Marketing]
)
SELECT REVERSE(Platform_Campaign_ID) AS Platform_Campaign_ID, EmailName
FROM Cte_Reverse
WHERE REVERSE(Platform_Campaign_ID) <> '2020'
AND REVERSE(Platform_Campaign_ID) <> ''
AND LEN(REVERSE(Platform_Campaign_ID)) = 4;
It is working for the most part, below is a screenshot of the result set.
The query I posted above extracts the 4 numbers to the right out of the initial value that is set for the column I am extracting out of. But I am unable to figure out how I can also have the query ignore cases when the right most value is -v2, -v1, etc. essentially anything with -v and whatever number version it is.
If you want four digits, then one method is:
select substring(emailname, patindex('%[0-9][0-9][0-9][0-9]%', emailname), 4)

tsql returns the right answer only when I specify the criteria in the where clause

I have some sql that will not return the rows I need unless I specify that as a criteria in the where clause. If I uncomment the part below that is commented out, it will give me the rows I want. If I leave it commented out, those rows are not returned in my result set.
Does this make sense? Can anyone see anything I'm doing wrong? Thanks.
SELECT
RTRIM(c.comp2) + '-' + l.Loc_Name,
MAX(RTRIM(g.mega_location_num) + '-' + g.mega_location_name)
FROM
mkt_share_comp c, gldm_location g, mkt_share_locs l
WHERE
RTRIM(c.comp1) = g.location_num
AND c.comp2 = l.Loc_No
AND LEN(c.comp2) = 5 AND c.is_deleted = 0 AND l.is_deleted = 0
--and g.mega_location_num = '450'
GROUP BY
RTRIM(c.comp2) + '-' + l.Loc_Name
ORDER BY
MAX(RTRIM(g.mega_location_num) + '-' + g.mega_location_name)
This comparison:
MAX(RTRIM(g.mega_location_num) + '-' + g.mega_location_name)
Will be doing a MAX based on the string value that you're constructing. So if there are any g.mega_location_num values which start with a digit greater than 4 (or start with 4 and have a second digit greater than 5, etc), then that value will be the MAX value returned.
To start to fix this, I would first switch to the ANSI join style that Kuya has suggested. I would then consider including an appropriate ROW_NUMBER() expression to locate the "genuine" maximum value from the g table and to be able to retrieve multiple columns from that maximal row (to allow the string construction to proceed)

How to select a list of 100 next sequence values from a database

select nextval ('mySchema.mySequence')
This command will return the next value of a sequence.
How can I get the next N values from a sequence in SQL?
My current setup uses postgreSQL, and Hibernate's native SQL queries, but any solution is appreciated.
Here is a link to an answer provided on a related question.
How to select multiple rows filled with constants?
The solution for Postgres, Oracle, and SQL Server are all different.
The Postgres solution is:
SELECT l
FROM generate_series(1, $n) l
In your case instead of select l you would select nextval('mySchema.mySequence')
You can define your sequence with INCREMENT BY 100 and then, when you get your next value N using SQL just use values N + 1, N + 1, ..., N + 99 in your Java code.
Please use this SQL query.
Note: it will work only in case of Oracle.
select your_sequence_name.nextval from dual connect by level <= 100

Sql Server Split and Concatenation

I have data in the following format in a sql server database table
[CPOID] [ContractPO] [ContractPOTitle]
1 10-SUP-CN-CNP-0001 Drytech
2 10-SUP-CN-CNP-0002 EC&M
I need to write a stored procedure to generate the following result
[CPOID] [ContractPO] [ContractPOTitle] [ConcatField]
1 10-SUP-CN-CNP-0001 Drytech CNP-0001-Drytech
2 10-SUP-CN-CNP-0002 EC&M CNP-0002-EC&M
where [ConcatField] generate the result using split the last two values of the [ContractPOTitle] column and combine with the [ContractPOTitle]
If the ContractPO field is always the same length, you could just do:
SELECT
CPOID,
ContractPO,
ContractPOTitle,
RIGHT(ContractPO, 8) + '-' + ContractPOTitle as [ConcatField]
FROM MyTable
Assuming that the length of the ContractPO field is not fixed AND we have to rely on stripping out the text after the next to last '-', the following SQL will work. It's a bit ugly, but these types of operations are necessary because there doesn't appear to be a LASTINDEX function available out of the box in SQL Server.
SELECT
CPOID,
ContractPO,
ContractPOTitle,
RIGHT(ContractPO, CHARINDEX('-', REVERSE(ContractPO), CHARINDEX('-', REVERSE(ContractPO)) + 1) - 1) + '-' + ContractPOTitle as [ConcatField]
FROM #myTable

SQL query--String Permutations

I am trying to create a query using a db on OpenOffice where a string is entered in the query, and all permutations of the string are searched in the database and the matches are displayed. My database has fields for a word and its definition, so if I am looking for GOOD I will get its definition as well as the definition for DOG.
You'll need a third column as well. In this column you'll have the word - but with the letters sorted in alphabetical order. For example, you'll have the word APPLE and in the next column the word AELPP.
You would sort the word your looking for - and run a some SQL code like
WHERE sorted_words = 'my_sorted_word'
for the word apple, you would get something like this:
unsorted sorted
AELPP APPLE
AELPP PEPLA
AELPP APPEL
Now, you also wanted - correct me if I'm wrong, but you want all the words that can be made with **any combination ** of the letters, meaning APPLE also returns words like LEAP and PEA.
To do this, you would have to use some programming language - you would have to write a function that preformed the above recursively, for example - for the word AELLP you have
ELLP
ALLP
AELP
and so forth.. (each time subtracting one letter in every combination, and then two letters in every combination possible ect..)
Basically, you can't easily do permutations in single SQL statement. You can easily do them in another language though, for example here's how to do it in C#: http://msdn.microsoft.com/en-us/magazine/cc163513.aspx
Ok, corrected version that I think handles all situations. This will work in MS SQL Server, so you may need to adjust it for your RDBMS as far as using the local table and the REPLICATE function. It assumes a passed parameter called #search_string. Also, since it's using VARCHAR instead of NVARCHAR, if you're using extended characters be sure to change that.
One last point that I'm just thinking of now... it will allow duplication of letters. For example, "GOOD" would find "DODO" even though there is only one "D" in "GOOD". It will NOT find words of greater length than your original word though. In other words, while it would find "DODO", it wouldn't find "DODODO". Maybe this will give you a starting point to work from though depending on your exact requirements.
DECLARE #search_table TABLE (search_string VARCHAR(4000))
DECLARE #i INT
SET #i = 1
WHILE (#i <= LEN(#search_string))
BEGIN
INSERT INTO #search_table (search_string)
VALUES (REPLICATE('[' + #search_string + ']', #i)
SET #i = #i + 1
END
SELECT
word,
definition
FROM
My_Words
INNER JOIN #search_table ST ON W.word LIKE ST.search_string
The original query before my edit, just to have it here:
SELECT
word,
definition
FROM
My_Words
WHERE
word LIKE REPLICATE('[' + #search_string + ']', LEN(#search_string))
maybe this can help:
Suppose you have a auxiliary Numbers table with integer numbers.
DECLARE #s VARCHAR(5);
SET #s = 'ABCDE';
WITH Subsets AS (
SELECT CAST(SUBSTRING(#s, Number, 1) AS VARCHAR(5)) AS Token,
CAST('.'+CAST(Number AS CHAR(1))+'.' AS VARCHAR(11)) AS Permutation,
CAST(1 AS INT) AS Iteration
FROM dbo.Numbers WHERE Number BETWEEN 1 AND 5
UNION ALL
SELECT CAST(Token+SUBSTRING(#s, Number, 1) AS VARCHAR(5)) AS Token,
CAST(Permutation+CAST(Number AS CHAR(1))+'.' AS VARCHAR(11)) AS
Permutation,
s.Iteration + 1 AS Iteration
FROM Subsets s JOIN dbo.Numbers n ON s.Permutation NOT LIKE
'%.'+CAST(Number AS CHAR(1))+'.%' AND s.Iteration < 5 AND Number
BETWEEN 1 AND 5
--AND s.Iteration = (SELECT MAX(Iteration) FROM Subsets)
)
SELECT * FROM Subsets
WHERE Iteration = 5
ORDER BY Permutation
Token Permutation Iteration
----- ----------- -----------
ABCDE .1.2.3.4.5. 5
ABCED .1.2.3.5.4. 5
ABDCE .1.2.4.3.5. 5
(snip)
EDBCA .5.4.2.3.1. 5
EDCAB .5.4.3.1.2. 5
EDCBA .5.4.3.2.1. 5
(120 row(s) affected)