SYBASE ASE String replace in WHERE clause - sql

I have a SYBASE ASE table with below values :
Table 1 :
**Value** **Status**
A STATUS 1
B STATUS 3
C STATUS 4
I have to filter the values based on the list of values like this .. STATUS1,STATUS2,STATUS3 (no space between values).
I want to remove the space/blanks from the value column from Table 1 and compare against the list.
I tried the below code and it wasn't working
select value ,status from Table 1
where str_replace(status,' ','') IN ('STATUS1','STATUS2','STATUS3')
select value ,status from Table 1
where str_replace(status,' ',NULL) IN ('STATUS1','STATUS2','STATUS3')
Any idea how to achieve without changing the list values

The latter one should work (apart from the Table 1 table name).
Note that an empty string in Sybase is often interpreted as a single space. See http://infocenter.sybase.com/help/index.jsp?topic=/com.sybase.infocenter.dc36271.1550/html/blocks/blocks311.htm

Related

Joining two tables in SQL in which one column has to be "cleaned"

I need to join two tables in SQL, which has two related columns (column ID1 in Table 1 and column ID in Table 2). ID1 in table 1 consists of 6 digits, whereas ID2 in table 2 consists of 6 digitis but an additional quotation marks (") in the beginning and end of the string. I need to remove these quotation marks and join the two tables to verify if there is any values reocurring in both columns.
I know how to remove first and last character of the string in table 2:
SELECT SUBSTRING ([ID2],2,Len([ID2])-2) FROM [dbo].[table2]
I need to join this new "trimmed" column with the other column from table 1.
Any suggestions?
Assuming you are using ms sql server db, and need everything from table1 and matched from table2 then:
sample:
table1 | table2
[ID] | [ID]
547832 | "547832"
-----------------------------
select table1.* , table2.*
from
db.tb1 table1
left join
db.tb2 table2
on
table1.[ID] = SUBSTRING([ID2],2,Len([ID2])-2) ;
First extract your trimmed column with different name by using 'AS' and then you can join the tables.
Try like the below
syntax: SELECT Substring( columnname , positon, length) AS Newcolumnname FROM Tablename;
EX: SELECT Substring(customerName,1,5) AS Newstr from Customer
Joins Table2 ON customer.Newstr = Table2.name;
I am using MS SQL, yes.
Thanks for the reply. However, why is it a left join and not an inner join here? Just curious.
So, essentially what I need to do is:
In the first table, I have around 10 columns, in the second table I have 5 columns. They all have different names, ID was just used as an example. Two of the columns from table 2 appears to have similar values as two of the columns from table 1 (one is an ID of 6 digits, the other is names). I want to remove the first and last character of the 6 digits in the ID column in table 2 and join that and the names column with ID and names from table 1. Hope it makes sense

map values to 3 object variables from 3 different select statements in ssis

I want to map values to 3 object variables from 3 different select statements by using single executesqltask.
Is that possible?
This can be done by applying a join between the three SQL statements using a fake ID. Here are the steps:
In the SQL Task Editor set the ResultSet to "Single row".
Enter your SQL statement something like that below, which will return a single row with three columns (each column is a result of a single record and column from the three joined SQL statements).
SELECT
a.test1,
b.test2,
c.test3
FROM
(SELECT top 1 '1' as ID, field_A as test1
FROM [dbo].[table1]) a
JOIN ( SELECT top 1 '1' as ID, field_B as test2
FROM [dbo].[table2]) b
on a.id = b.id
JOIN ( SELECT top 1 '1' as ID, field_C as test3
FROM [dbo].[table3]) c
on a.id = c.id
Select Result Set and add three new results names "0", "1" and "2". Each one will map to one of the three variables names you've defined in the package. You must use result names of 0, 1 and 2. "0" matches that returned from the first column of the SQL statement, "1" from the second column and "2" from the third column.
Hope this helps and please indicate if this answers your question.

Insert records into a table based on value of a record in another table

I am trying to create a quotation system using Microsoft Access 2013.
Currently, my main issue to trying to write a query that selects all records from a table (itemquote) that have a certain quoteID matching the quoteID coming from another table (currentquote), and then inserts the results into a new table (quoteditems).
Here is a basic example of the tables:
ItemQuote
UniqueID ItemID QuoteID BuyPrice SellPrice
1 1 1 10.00 11.00
2 8 2 07.00 14.00
3 4 5 01.12 03.00
CurrentQuote
CurrentQuoteID
1
My current attempt at writing the query looks like this:
INSERT INTO tblQuotedItems
SELECT *
FROM tblQuoteAsBuiltAndLabelling
INNER JOIN tblCurrentQuote
ON tblQuoteAsBuiltAndLabelling.QuoteID = tblCurrentQuote.CurrentQuoteID;
The resulting error message is "The INSERT INTO statement contains the following unknown field name: 'CurrentQuoteID'. Make sure you have typed the name correctly, and try the operation again." (Error 3127)
What should I do to my query to make it achieve the desired result? Thanks in advance.
The problem may be because your tblQuotedItems does not have the same number of column what your Select Query Returns.
So to resolve this, You can specified individual columns in INSERT Statement, and that will solve your problem.
You can not specify column names in the insert if the columns in the select are in the same order as in the table definition. Possibly, the columns in the current quote might be the same. If so, this might work:
INSERT INTO tblQuotedItems
SELECT tblCurrentQuote.*
FROM tblQuoteAsBuiltAndLabelling INNER JOIN
tblCurrentQuote
ON tblQuoteAsBuiltAndLabelling.QuoteID = tblCurrentQuote.CurrentQuoteID;
However, I strongly recommend that you include column names explicitly when you do inserts:
INSERT INTO tblQuotedItems(col1, col2, . . .)
SELECT col1, col2, . . .
FROM tblQuoteAsBuiltAndLabelling INNER JOIN
tblCurrentQuote
ON tblQuoteAsBuiltAndLabelling.QuoteID = tblCurrentQuote.CurrentQuoteID;

SQL statement to return data from a table in an other sight

How would the SQL statement look like to return the bottom result from the upper table?
The last letter from the key should be removed. It stands for the language. EXP column should be split into 5 columns with the language prefix and the right value.
I'm weak at writing more or less difficult SQL statements so any help would be appreciated!
The Microsoft Access equivalent of a PIVOT in SQL Server is known as a CROSSTAB. The following query will work for Microsoft Access 2010.
TRANSFORM First(table1.Exp) AS FirstOfEXP
SELECT Left([KEY],Len([KEY])-2) AS [XKEY]
FROM table1
GROUP BY Left([KEY],Len([KEY])-2)
PIVOT Right([KEY],1);
Access will throw a circular field reference error if you try to name the row heading with KEY since that is also the name of the original table field that you are deriving it from. If you do not want XKEY as the field name, then you would need to break apart the above query into two separate queries as shown below:
qsel_table1:
SELECT Left([KEY],Len([KEY])-2) AS XKEY
, Right([KEY],1) AS [Language]
, Table1.Exp
FROM Table1
ORDER BY Left([KEY],Len([KEY])-2), Right([KEY],1);
qsel_table1_Crosstab:
TRANSFORM First(qsel_table1.Exp) AS FirstOfEXP
SELECT qsel_table1.XKEY AS [KEY]
FROM qsel_table1
GROUP BY qsel_table1.XKEY
PIVOT qsel_table1.Language;
In order to always output all language columns regardless of whether there is a value or not, you need to spike of those values into a separate table. That table will then supply the row and column values for the crosstab and the original table will supply the value expression. Using the two query solution above we would instead need to do the following:
table2:
This is a new table with a BASE_KEY TEXT*255 column and a LANG TEXT*1 column. Together these two columns will define the primary key. Populate this table with the following rows:
"AbstractItemNumberReportController.SelectPositionen", "D"
"AbstractItemNumberReportController.SelectPositionen", "E"
"AbstractItemNumberReportController.SelectPositionen", "F"
"AbstractItemNumberReportController.SelectPositionen", "I"
"AbstractItemNumberReportController.SelectPositionen", "X"
qsel_table1:
This query remains unchanged.
qsel_table1_crosstab:
The new table2 is added to this query with an outer join with the original table1. The outer join will allow all rows to be returned from table2 regardless of whether there is a matching row in the table1. Table2 now supplies the values for the row and column headings.
TRANSFORM First(qsel_table1.Exp) AS FirstOfEXP
SELECT Table2.Base_KEY AS [KEY]
FROM Table2 LEFT JOIN qsel_table1 ON (Table2.BASE_KEY = qsel_table1.XKEY)
AND (Table2.LANG = qsel_table1.Language)
GROUP BY Table2.Base_KEY
PIVOT Table2.LANG;
Try something like this:
select *
from
(
select 'abcd' as [key], right([key], 1) as id, expression
from table1
) x
pivot
(
max(expression)
for id in ([D], [E])
) p
Demo Fiddle

How to compare string data to table data in SQL Server - I need to know if a value in a string doesn't exist in a column

I have two tables, one an import table, the other a FK constraint on the table the import table will eventually be put into. In the import table a user can provide a list of semicolon separated values that correspond to values in the 2nd table.
So we're looking at something like this:
TABLE 1
ID | Column1
1 | A; B; C; D
TABLE 2
ID | Column2
1 | A
2 | B
3 | D
4 | E
The requirement is:
Rows in TABLE 1 with a value not in TABLE 2 (C in our example) should be marked as invalid for manual cleanup by the user. Rows where all values are valid are handled by another script that already works.
In production we'll be dealing with 6 columns that need to be checked and imports of AT LEAST 100k rows at a time. As a result I'd like to do all the work in the DB, not in another app.
BTW, it's SQL2008.
I'm stuck, anyone have any ideas. Thanks!
Seems to me you could pass ID & Column1 values from Table1 to a Table-Valued function (or a temp table in-line) which would parse the ;-delimited list, returning individual values per record.
Here are a couple options:
T-SQL: Parse a delimited string
Quick T-Sql to parse a delimited string
The result (ID, value) from the function could be used to compare (unmatched query) against values in Table 2.
SELECT tmp.ID
FROM tmp
LEFT JOIN Table2 ON Table2.id = tmp.ID
WHERE Table2.id is null
The ID results of the comparison would then be used to flag records in Table 1.
Perhaps inserting those composite values into 'TABLE 1' may have seemed like the most convenient solution at one time. However, unless your users are using SQL Server Management Studio or something similar to enter the values directly into the table then I assume there must be a software layer between the UI and the database. If so, you're going to save yourself a lot headaches both now and in the long run by investing a little time in altering your code to split the semi-colon delimited inputs into discrete values before inserting them into the database. This will result in 'TABLE 1' looking something like this
TABLE 1
ID | Column1
1 | A
1 | B
1 | C
1 | D
It's then trivial to write the SQL to find those IDs which are invalid.
If it is possible, try putting the values in separate rows when importing (instead of storing it as ; separated).
This might help.
Here is an easy and straightforward solution for the IDs of the invalid rows, despite its lack of performance because of string manipulations.
select T1.ID
from [TABLE 1] T1
left join [TABLE 2] T2
on ('; ' + T1.COLUMN1 + '; ') like ('%; ' + T2.COLUMN2 + '; %')
where T1.COLUMN1 is not null
group by T1.ID
having count(*) < len(T1.COLUMN1) - len(replace(T1.COLUMN1, ';', '')) + 1
There are two assumptions:
The semicolon-separated list does not contain duplicates
TABLE 2 does not contain duplicates in COLUMN2.
The second assumption can easily be fixed by using (select distinct COLUMN2 from [TABLE 2]) rather than [TABLE 2].