Querying for multiple values in multiple columns - sql

How would I search multiple (in this example, say 2) columns for an array of values?
For example, here is my table Documents :
1. DocNumber (varchar)
2. CompanyCode (varchar)
3. Data1 (varchar)
4. Data2 (varchar)
5. Data3 (varchar)
DocNumber and CompanyCode form the composite primary key of this table. Say I have a set of values which I want to search in the database such as:
DocNumber
CompanyCode
1001
101
1002
102
1004
103
How would I find these unique combinations in the table with one query?
I could use in:
select *
from Documents
where DocNumber in :docNumbers and CompanyCode in :companyCodes
But that would also return records with DocNumber 1001 and CompanyCode 102 (all combinations of the 2 lists). I want to avoid that.
I am using HANA DB (through a Spring Boot application).
Sample table data:
table data
Expected response:
expected response
Response I get:
current response

The IN predicate also works with tuples. Please find a minimal example:
SELECT *
FROM
(
SELECT 'A1' AS DOCNUMBER, 'A2' AS COMPANYCODE FROM DUMMY
)
WHERE (DOCNUMBER, COMPANYCODE) IN (('A1', 'A2'),('B1', 'B2'))
Further details and examples can be found in the documentation.

Related

INSERT INTO with foreign key and data from another table

I have a table where the most important information is that it is auto-incremented, the rest of the fields in the database are not relevant. Before inserting the data into the table, I created a "helper" table to store the newly created IDs in this table.
I have a second table like this - also the most important information is that the ID is auto-incremented, and the other data is not relevant to this example. In this case, I have also created an auxiliary table that stores the newly created ID values from this table.
Now I would like to take the values from auxiliary table 1 and 2 and insert them into a third table that will take the smallest ID from auxiliary table 1 and the smallest ID from auxiliary table 2 and insert them as a record into this third table, for example:
Record ID of third table | Smallest ID from first table | Smallest ID from third table.
I have no idea how to build the query constructs in my case - could someone give me some advice, or ready-made (different) code to follow?
My code:
DECLARE #inserted1 TABLE (contact_id udt_id)
INSERT INTO t_usr_contact (contact_firstname, contact_lastname)
OUTPUT INSERTED.contact_id INTO #inserted1(contact_id)
SELECT
'Firma',
'Temporary_value'
FROM t_sup_supplier AS sup
WHERE sup.sup_id IN (175,176) AND sup.grp_id IS null
DECLARE #inserted2 TABLE (grp_id udt_id)
INSERT INTO t_usr_group (grp_label_en)
OUTPUT INSERTED.grp_id INTO #inserted2(grp_id)
SELECT
'Supplier contact'
FROM t_sup_supplier AS sup2
WHERE sup2.sup_id IN (175,176) AND sup2.grp_id IS null
INSERT INTO t_usr_contact_group (grp_id, contact_id)
I would like to go the easiest way, which is as below, but it doesnt work :/.
VALUES (#inserted2.grp_id, #inserted2.contact_id)
As for the data example, after the insert in the first table I will get the following records and in the auxiliary table number 1 I will get the following records:
**Table t_usr_contact:**
175 - Firma - Temporary_value
176 - Firma - Temporary_value
**Table #inserted1:**
175
176
**Table t_usr_group:**
201 - Supplier_contact
202 - Supplier_contact
**Table #inserted2:**
201
202
**Table t_usr_contact_group:**
201 - 175
202 - 176
I've got no idea what you're ultimately trying to do, but if you want two tables each with N rows to become one table made from the columns of the two input tables, like you've got in your example (where your table of 175,176 and your table of 201,202 shall become a table of 175|201,176|202) then you need to join them. To join them you need a key. You haven't got a key so you'll have to fake one:
INSERT INTO thirdtable
SELECT contact_id,grp_id
FROM
(SELECT *, ROW_NUMBER() OVER(ORDER BY contact_id) as FakeKey FROM #inserted1) x
INNER JOIN
(SELECT *, ROW_NUMBER() OVER(ORDER BY grp_id) as FakeKey FROM #inserted2) x
ON x.FakeKey = y.FakeKey
This, of course, joins the data in a very arbitrary fashion based on the order of the assigned IDs. If you want some specific order, like contact 175 exists first and has to get group 202, then you can make the query that inserts the group (eg 202) based on the input 175 output the 175 and the 202 together into a (temp) common table then split it into the detail and middleman tables after

MS Access convert and summarise two rows into columns with unique names

I'm really struggling to 'Transform' or pivot this simple two column table, is there a way ?
All the solutions I have found so far ( pivot / transform / crosstab etc) require the data to have some kind of third field index number in order to create the column names. In my case each Itemcode can have any number of Itemimage and those itemimage sometimes are valid for more than one Itemcode. Typically the number of itemimage will be less than 20 but there are tens of thousands of Itemcode.
transform Table1:
Itemcode Itemimage
12345 image-a.jpg
12345 image-b.jpg
23456 image-c.jpg
23456 image-d.jpg
23456 image-a.jpg
34567 image-e.jpg
45678 image-a.jpg
into a table like this:
Itemcode Itemimage1 Itemimage2 Itemimage3
12345 image-a.jpg image-b.jpg null
23456 image-c.jpg image-d.jpg image-a.jpg
34567 image-e.jpg null null
45678 image-a.jpg null null
The nearest I have come to getting this to work is
TRANSFORM First(MySubQuery.Itemimage) AS FirstOfItemimage
SELECT MySubQuery.Itemcode
FROM (SELECT [Itemcode], 'Itemimage' & [Number] AS ColumnName, [Itemimage] FROM Table1) AS MySubQuery
GROUP BY MySubQuery.Itemcode
PIVOT MySubQuery.ColumnName;
but this requires the creation of a [Number] column in Table1 to create the incremental index number for the columns.
day 3 of working on this ... beginning to think it cannot be done with a single query and will require a Visual Basic macro to sort into Itemcode order then create an array which is read out to a new table. Really need some help as I have never programed in VB.
note: it is important that the resulting table is in the same order as Table1 This is because the data in Table1 is in a specific order as provided to me by a 3rd party. The sample data above shows only the Itemimage field but I have similar data with Itemdescription containing sentences where the sequence must be maintained in order to keep its grammatical meaning unchanged.

Assign unique ID's to three tables in SELECT query, ID's should not overlap

I am working on SQL Sever and I want to assign unique Id's to rows being pulled from those three tables, but the id's should not overlap.
Let's say, Table one contains cars data, table two contains house data, table three contains city data. I want to pull all this data into a single table with a unique id to each of them say cars from 1-100, house from 101 - 200 and city from 300- 400.
How can I achieve this using only select queries. I can't use insert statements.
To be more precise,
I have one table with computer systems/servers host information which has id from 500-700.
I have another tables, storage devices (id's from 200-600) and routers (ids from 700-900). I have already collected systems data. Now I want to pull storage systems and routers data in such a way that the consolidated data at my end should has a unique id for all records. This needs to be done only by using SELECT queries.
I was using SELECT ABS(CAST(CAST(NEWID() AS VARBINARY) AS INT)) AS UniqueID and storing it in temp tables (separate for storage and routers). But I believe that this may lead to some overlapping. Please suggest any other way to do this.
An extension to this question:
Creating consistent integer from a string:
All I have is various strings like this
String1
String2Hello123
String3HelloHowAreYou
I Need to convert them in to positive integers say some thing like
String1 = 12
String2Hello123 = 25
String3HelloHowAreYou = 4567
Note that I am not expecting the numbers in any order.Only requirement is number generated for one string should not conflict with other
Now later after the reboot If I do not have 2nd string instead there is a new string
String1 = 12
String3HelloHowAreYou = 4567
String2Hello123HowAreyou = 28
Not that the number 25 generated for 2nd string earlier can not be sued for the new string.
Using extra storage (temp tables) is not allowed
if you dont care where the data comes from:
with dat as (
select 't1' src, id from table1
union all
select 't2' src, id from table2
union all
select 't3' src, id from table3
)
select *
, id2 = row_number() over( order by _some_column_ )
from dat

SQL If-Else logic based on value of one table

I have the following tables:
Production Table
SerialNumber WorkOrderNumber ItemName ItemType
1234 A2234 ASD 1
1234 A2234 ASD-T 2
1111 B2234 ZXC-T 2
WorkOrder Table
WorkOrderNumber ItemName ItemType
B2234 ZXC 1
B2234 ZXC-T 2
B2234 ZXC-C 3
Scenario: User inputs Serial Number, wants to get the item name of itemtype = 1 from either production table or workorder table
Desired Result
User input Serial number 1234 in application:
ItemName : ASD [Found in production table]
User input Serial number 1111 in application:
ItemName : ZXC [Found in workorder table]
Production and Workorder table is heavily simplified for demonstration purposes. The table contains millions of rows each. I need to come up with a performant query to get the item name.
The only solution I have thought of is to do the following
Use stored procedure and write an if-else logic
Check if the item type of the entered serial number is 1. If true, return itemname.
If itemtype is not 1, get the itemname from workorder table with itemtype = 1
But I'm not sure if that's a preferred method for performance and I feel kinda icky about putting business logic in database.
How would one handle this problem elegantly?
Try this:
select top 1 pt.serialNumber,pt.workOrderNumber,
isNull(wt.ItemName,pt.ItemName) as NameToReturn
from prodTable pt
left join worktable wt on pt.WorkOrderNumber=wt.workOrderNumber and wt.itemType=1
where pt.serialNumber = <input>
order by p1.itemType
Not sure I understand all your requirements, but the above should give you a start point. It finds the part in the prodTable and optionally finds a part in the work Item table. The is Null logic assumes that if a type one exists in Work table, it will be used. You might need to tweak this to a case statement if your rules are different (i.e. 1 in prod table should override worktable)

Fetch a single field from DB table into itab

I want to fetch the a field say excep_point from a transparent table z_accounts for the combination of company_code and account_number. How can I do this in ABAP SQL?
Assume that table structure is
|company_code | account_number | excep_point |
Assuming you have the full primary key...
data: gv_excep_point type zaccounts-excep_point.
select single excep_point
into gv_excep_point
from zaccounts
where company_code = some_company_code
and account_number = some_account_number.
if you don't have the full PK and there could be multiple values for excep_point
data: gt_excep_points type table of zaccounts-excep_point.
select excep_point
into table gt_excep_points
from zaccounts
where company_code = some_company_code
and account_number = some_account_number.
There is at least another variation, but those are 2 I use most often.
For information only. When you selects data into table you can write complex expressions to combine different fields. For example, you have internal table (itab) with two fields "A" and "B". And you are going to select data from DB table (dbtab) wich have 6 columns - "z","x","y","u","v","w". And for example each field is type char2 You aim to cimbine "z","x","y","u" in "A" field of internal table and "v","w" in "B" field. You can write simple code:
select z as A+0(2)
x as A+2(2)
y as A+4(2)
u as A+6(2)
v as B+0(2)
w as B+2(2) FROM dbtab
INTO CORRESPONDING FIELDS OF TABLE itab
WHERE <where condition>.
This simple code makes you job done very simple
In addition to Bryans answer, here is the official online documentation about Open SQL.