Empty row in Teradata query result - sql

I know this might sound weird and but after executing a Teradata query, I am getting the result as such:
| ID | Name |
+------+---------+
| 1007 | Raj |
| | |
| 1001 | Sanjib |
| 1008 | Suman |
| 1004 | Mohan |
The 2nd row is just blank. (Sorry, could not edit properly but I hope you get the point) The query is pretty simple.
SELECT DISTINCT column_names
FROM table1
FULL OUTER JOIN table2 ON table1.ID = table2.ID;
I do not have access to its' DDL statements.
There was also another scenario where this same table was in the output, just without any row elements, just the column names.
I am using SQL WORKBENCH/J. Am I missing something?

Related

Optimize a JOIN query, for multiple correspondances between tables

I am trying to optimize a function (MySQL), but the JOIN is still not completely understood (I try to make a simple example) :
I have 2 tables :
Table ITEMS
ID | ID_ORDER | ID_BOX | NAME
001 | 2564 | 123 | SPOON_1
002 | 2564 | 123 | SPOON_2
006 | 2564 | 123 | SHOES_2
007 | 2564 | 123 | SHOES_1
003 | 2565 | 124 | SPOON_1
004 | 2565 | 124 | SPOON_2
008 | 2565 | 124 | SHOES_1
009 | 2565 | 124 | SHOES_2
005 | 2565 | 125 | SPOON_1
010 | 2565 | 125 | SHOES_1
The description of objects are linked to the ITEM table by ID_CONTRACT, and NAME.(Not possible to have 2 items with same name inside the same contract).
Table DESCRIPTION :
ID_ORDER | NAME_ITEM | LENGTH | WIDTH | ....
2564 | SPOON_1 | 200 | 20 ...
2564 | SPOON_2 | 300 | 20 ...
2564 | SHOES_1 | 500 | 20 ...
2564 | SHOES_2 | 600 | 20 ...
Now, I need to know all items I have in the contract, with their description, and I use this query :
SELECT *,description.* FROM items INNER JOIN description
ON (description.ID_CONTRACT=items.ID_CONTRACT AND description.NAME_ITEM=items.NAME)
WHERE ID_CONTRACT= 2564
First, I just read it is not correct query (I need to copy all description fields by hand in query?), because ID_CONTRACT is in both tables, and sometimes it gives me mistake(sometimes not), and I read there that it is not possible to ignore duplicates.
Then I am wondering, as I make a select on ITEMS table, MySQL is looking for each line a correspondance in DESCRIPTION table?
Is there a way to optimize query (another kind of JOIN), so it will not search everytime in ITEMS table, when he meets 2 elements (or more) in ITEMS, with same ID_CONTRACT/NAME ?
select * mean select all the columns from all the tables
and in your case this is like select items.,description. so with the syntax SELECT ,description. seems you are trying to select two time the columns for table description
due the fact you have the same column name ID_CONTRACT in both table this produce an ambiguity on coumn name for the DB engine during the join.
for avoid this you simply need a full reference name in join columns name eg:
table1.col1 = table2.col1
this way the db engino know which column form each table must be use for join
SELECT items.*, description.*
FROM items
INNER JOIN description ON description.ID_CONTRACT=items.ID_CONTRACT
AND description.NAME_ITEM=items.NAME
WHERE ID_CONTRACT= 2564
for your second part of question
MySQL is looking for each line a correspondance in DESCRIPTION table?
yes.
A relation db work on sets of data and retrieve all the correspondance between the tables
if really the rows are duplicated you could retrive the distinct result using
select DISTICNT col1, col2..
tipically a select * from a join on correctly normalized data set don't produce dulicated rows (at least you value in one column differ beetween the rows)
but if some column result are not important for you and can be omittedc form the result, this case can produce a result with duplicated row and you can perform a selective select using only the column name you really need and apply the disctint clause

Sql Server how to find values in different tables that have different suffix

I'm struggling to find a value that might be in different tables but using UNION is a pain as there are a lot of tables.
[Different table that contains the suffixes from the TestTable_]
| ID | Name|
| -------- | -----------|
| 1 | TestTable1 |
| 2 | TestTable2 |
| 3 | TestTable3 |
| 4 | TestTable4 |
TestTable1 content:
| id | Name | q1 | a1 |
| -------- | ---------------------------------------- |
| 1 | goose | withFeather? |featherID |
| 2 | rooster| withoutFeather?|shinyfeatherID |
| 3 | rooster| age | 20 |
TestTable2 content:
| id | Name | q1 | a1 |
| -------- | ---------------------------------------------------|
| 1 | brazilian_goose | withFeather? |featherID |
| 2 | annoying_rooster | withoutFeather?|shinyfeatherID |
| 3 | annoying_rooster | no_legs? |dead |
TestTable3 content:
| id | Name | q1 | a1 |
| -------- | ---------------------------------------- |
| 1 | goose | withFeather? |featherID |
| 2 | rooster| withoutFeather?|shinyfeatherID |
| 3 | rooster| age | 15 |
Common columns: q1 and a1
Is there a way to parse through all of them to lookup for a specific value without using UNION because some of them might have different columns?
Something like: check if "q1='age'" exists in all those tables (from 1 to 50)
Select q1,*
from (something)
where q1 exists in (TestTable_*)... or something like that.
If not possible, not a problem.
You could use dynamic SQL but something I do in situations like this where I have a list of tables that I want to quickly perform the same actions on is to either use a spreadsheet to paste the list of tables into and type a query into the cell with something like #table then use the substitute function to replace it.
Alternative I just paste the list into SSMS and use SHIFT+ALT+ArrowKey to select the column and start typing stuff out.
So here is my list of tables
Then I use that key combo. As you can see my cursor has now selected all those rows.
Now I can start typing and all rows selected will get the input.
Then I just go to the other side of the table names and repeat the action
It's not a perfect solution but it's quick a quick and dirty way of doing something repetitive quickly.
If you want to find all the tables with that column name you can use information schema.
Select table_name from INFORMATION_SCHEMA.COLUMNS where COLUMN_NAME = 'q1'
Given the type of solution you are after I can offer a method that I've had to use on legacy systems.
You can query sys.columns for the name of the column(s) you need to find in N tables and join using object_id to sys.tables where type='U'. This will give you a list of table names.
From this list you can then build a working query for each table, and depending on your requirements (is this ad-hoc?) either just manually execute it yourself of build a procedure that will do it for you using sp_executesql
Eg
select t.name, c.name
into #workingtable
from sys.columns c
join sys.tables t on t.object_id=c.object_id
where c.name in .....
psudocode:
begin loop while rows exist in #working table
select top 1 row from #workingtable
set #sql=your query specific to that table and column(s)
exec(#sql) / sp_executesql / try/catch as necessary
delete row from working table
end loop
Hopefully that give ideas at least for how you might implement your requirements.

MS Access String Replacement Query

I have 2 tables, Table1 and Table2. I need to replace a string or a series of strings (separated by commas) in Table1 referred from Table2.
I did a query on this but no luck:
TableNew: Iif(Instr([Table1.ColumnX1],[Table2.ColumnY1],Replace([Table1.ColumnX1],[Table2.ColumnY1],[Table2.ColumnY2]),[Table1.ColumnX1])
What i wanted to achieve was like this, in Table1 ColumnX1 there is:
A,B,C,1,2,3,4,D,E,F,5,6
Then in Table2 I have:
+----------+-----------+
| ColumnY1 | ColumnY2 |
+----------+-----------+
| A | Z |
| B | Y |
| C | X |
| D | W |
| E | V |
| F | U |
+----------+-----------+
After running that Query, it would result to
Z,Y,X,1,2,3,4,W,V,U,5,6
I would like this to run in each row available in Table1.
Thanks in advance.
You can use a query such as the following to modify the values held by Table1:
update table1 inner join table2 on instr(1, table1.columnx1, table2.columny1) > 0
set table1.columnx1 = replace(table1.columnx1, table2.columny1, table2.columny2)
Note that the joins implemented in the above query cannot be displayed by the MS Access query designer, however, it is valid SQL which may be successfully executed by the JET database engine used by MS Access.

Filling information from same and other tables in SQL

For my further work I need to create a lookup table where all the different IDs my data has (because of different sources) are noted.
It has to look like this:
Lookup_Table:
| Name | ID_source1 | ID_source2 | ID_source3 |
-----------------------------------------------
| John | EMP_992 | AKK81239K | inv1000003 |
Note, that Name and ID_Source1 are coming from the same table. The other IDs are coming from different tables. They share the same name value, so e.g. source 2 looks like this:
Source2 Table:
| Name | ID |
--------------------
| John | AKK81239K |
What is the SQL code to accomplish this? Im using Access and it doesnt seem to work with this code for source 2:
INSERT INTO Lookup_Table ([ID_Source2])
SELECT [Source2].[ID]
FROM Lookup_Table LEFT JOIN [Source2]
ON [Lookup_Table].[Name] = [Source2].[Name]
It just adds the ID from Source2 in a new row:
| Name | ID_source1 | ID_source2 | ID_source3 |
-----------------------------------------------
| John | EMP_992 | | |
| | | AKK81239K | |
Hope you guys can help me.
You're looking for an UPDATE query, not an INSERT query.
An UPDATE query updates existing records. An INSERT query inserts new records into a table.
UPDATE Lookup_Table
INNER JOIN [Source2] ON [Lookup_Table].[Name] = [Source2].[Name]
SET [ID_Source2] = [Source2].[ID]

Why is this Query not Updateable?

I was looking to provide an answer to this question in which the OP has two tables:
Table1
+--------+--------+
| testID | Status |
+--------+--------+
| 1 | |
| 2 | |
| 3 | |
+--------+--------+
Table2
+----+--------+--------+--------+
| ID | testID | stepID | status |
+----+--------+--------+--------+
| 1 | 1 | 1 | pass |
| 2 | 1 | 2 | fail |
| 3 | 1 | 3 | pass |
| 4 | 2 | 1 | pass |
| 5 | 2 | 2 | pass |
| 6 | 3 | 1 | fail |
+----+--------+--------+--------+
Here, the OP is looking to update the status field for each testID in Table1 with pass if the status of all stepID records associated with the testID in Table2 have a status of pass, else Table1 should be updated with fail for that testID.
In this example, the result should be:
+--------+--------+
| testID | Status |
+--------+--------+
| 1 | fail |
| 2 | pass |
| 3 | fail |
+--------+--------+
I wrote the following SQL code in an effort to accomplish this:
update Table1 a inner join
(
select
b.testID,
iif(min(b.status)=max(b.status) and min(b.status)='pass','pass','fail') as v
from Table2 b
group by b.testID
) c on a.testID = c.testID
set a.testStatus = c.v
However, MS Access reports the all-too-familiar, 'operation must use an updateable query' response.
I know that a query is not updateable if there is a one-to-many relationship between the record being updated and the set of values, but in this case, the aggregated subquery would yield a one-to-one relationship between the two testID fields.
Which left me asking, why is this query not updateable?
You're joining in a query with an aggregate (Max).
Aggregates are not updateable. In Access, in an update query, every part of the query has to be updateable (with the exception of simple expressions, and subqueries in WHERE part of your query), which means your query is not updateable.
You can work around this by using domain aggregates (DMin and DMax) instead of real ones, but this query will take a large performance hit if you do.
You can also work around it by rewriting your aggregates to take place in an EXISTS or NOT EXISTS clause, since that's part of the WHERE clause thus doesn't need to be updateable. That would likely minimally affect performance, but means you have to split this query in two: 1 query to set all the fields to "pass" that meet your condition, another to set them to "fail" if they don't.