SQL Server to concatenate query results and insert the into another table - sql-server-2008

I have table A and a table B. Table A contains the product data, Table B contains the images for each product. One line per image.
I need a SQL statement created to Loop through table A, get the product ID, then concatenate the result set and insert it into one field in table A.
Table A:
P-ID, Value1, Value2, Value3, ImageLocation
35 Name Price description
Table B:
P-ID, ImageLocation
35 /upload/directory/imagename.jpg
35 /upload/directory/imagename2.jpg
35 /upload/directory/imagename3.jpg
End result:
TableA:
P-ID, Value1, Value2, Value3, ImageLocation
35 Name Price description /up/dir/image.jpg,/up/dir/image2.jpg,/up/dir/image3.jpg
How on earth do I SQL-ize this?
Thanks from the newbie!!!!

Multivalued columns are frowned upon... and there's not a graceful way to do this in Sql Server - but, you can use FOR XML PATH:
SELECT PID, Value1, Value2, Value3, STUFF((
SELECT ',' + ImageLocation
FROM TableB b
WHERE b.PID = a.PID
FOR XML PATH('')
), 1, 1, '') AS ImageLocation
FROM TableA a
Sql Fiddle
But again, do you really need to be doing this in your Sql query, or is this something that you can handle in your application / presentation?

You could try something along these lines:
Select p.id, location || '/' ||......
From
(
Select * from tableA a, tableB b
Where a.id = b.id
)
I don't know which DBMS you are using, so please see which string con. is appropriate

Related

How to merge two databases, with same data, but with different PKs, without duplicated fields?

I have two mdb files.
I can also convert it to MySQL database, if necessary.
How can I merge these two different dbs to a single one?
The idea is to get all info form both dbs and merge into one, without duplicating any client.
The problem is that both bds have the same clients, and different ones, but the PKs of the clients aren't the same on them.
Every line has a unique field, I guess it can help somehow.
Any idea of how can I do that?
Select a UNION all columns except the PKs will give you only distinct rows:
insert into new_table (<non-pk columns>)
select <non-pk columns> from tableA
union
select <non-pk columns> from tableB
Note: union removes duplicates.
I would run an UPDATE to populate one of the tables w/ all info available.
Assuming the first table has all names that the second table has (that there are no name values in table 2 that are not in table 1) you should be able to run the following update to make the first table complete:
update tclient1 t join (select name,
max(tel) as tel_filled,
max(address) as add_filled
from (select name, tel, address
from tclient1
union all
select name, tel, address
from tclient2) x
group by name) x on t.name = x.name
set t.tel = x.tel_filled and t.address = x.add_filled;
See fiddle: http://sqlfiddle.com/#!2/3e7dc/1/0
Disable foreign keys (see here)
Update FK in the 2nd DB so make them unique, for instance:
update Client
set id_client = id_client + 100000000;
update History
set id_client = id_client + 100000000,
id_history = id_history + 10000000;
Enable FKs to check integrity
Export 2nd DB as SQL-inserts and execute it in the 1st DB.
Use backups, please.
Here is one approach that assumes that name is the match between the two rows. It just counts the numbers that are filled in and chooses the appropriate source. This version uses union all with a comparison in the where using >= or <:
insert into client(id, name, tel, address)
select id, name, tel, address
from db1.client c1
where ((id is not null) + (tel is not null) + (address is not null)) >=
(select (id is not null) + (tel is not null) + (address is not null)
from db2.client c2
where c1.name = c2.name
)
)
union all
select id, name, tel, address
from db2.client c2
where ((id is not null) + (tel is not null) + (address is not null)) >
(select (id is not null) + (tel is not null) + (address is not null)
from db1.client c1
where c2.name = c1.name
)
);
Note: the above version assumes that name is in both tables (as in the example in your question) and there are no duplicates. It can be easily modified if this isn't the case.

Select up to 3 different fields in a table based on the value in another table?

Ive seen plenty of examples but none seem to get me where I need it.
I want to Select 1 field from table A, then Check table B for a value, if that value is true(boolean) then also Select field 2 and 3 from table A to return all 3 fields. So if value from B is false only 1 field is selected from table A, if true, all 3 are selected.
Select Field1
, Case
When Exists (
Select 1
From TableB
Where SomeField = 1
And ...
) Then TableA.Field2
Else Null
End As Field2
, Case
When Exists (
Select 1
From TableB
Where SomeField = 1
And ...
) Then TableA.Field3
Else Null
End As Field3
From TableA
Update
The above solution works fine if what you want is a three column result every time even if some of those columns are null. However, if what you want is a different number of columns returned based on the query, then this is something that cannot be done in a single query. The SQL language was not geared to handle on-the-fly schema generation. My suggestion would first be to evaluate why you want a different number of columns from the same query and determine if you cannot simply handle the scenario in your middle-tier where column 2 or 3 is NULL. That is by far the simplest solution and could be done in a single query:
Select TableA.Field1, TableA.Field2, TableA.Field3
, (
Select TableB.SomeBooleanColumn
From TableB
) As TableBValue
From TableA
Your middle-tier code would then determine whether to do something with Field2 and Field3.
That said, if you insist on having two column structures, you need two queries:
Select TableA.Field1
From TableA
Where Exists (
Select 1
From TableB
Where TableB.SomeColumn = 0
)
After calling this query, you would evaluate whether you got a row. If you got no rows, you could then call this query:
Select TableA.Field1, TableA.Field2, TableA.Field3
From TableA
Where Exists (
Select 1
From TableB
Where TableB.SomeColumn = 1
)
What hasn't be stated in the OP is the scenario where there is no row in TableB.
Use case expressions:
select A.field1,
case B.boolValue when 1 then A.field2 end AS field2,
case B.boolValue when 1 then A.field3 end AS field3
from TableA A join TableB B on A.? = B.?
I don't know what your A and B tables are linked on so you'll have to fill in the ? marks. This will return null values for field2 and field3 when B.boolValue is false.

sql query for deleting rows with NOT IN using 2 columns

I have a table with a composite key composed of 2 columns, say Name and ID. I have some service that gets me the keys (name, id combination) of the rows to keep, the rest i need to delete. If it was with only 1 row , I could use
delete from table_name where name not in (list_of_valid_names)
but how do I make the query so that I can say something like
name not in (valid_names) and id not in(valid_ids)
// this wont work since they separately dont identity a unique record or will it?
Use mysql's special "multiple value" in syntax:
delete from table_name
where (name, id) not in (select name, id from some_table where some_condition);
If your list is a literal list, you can still use this approach:
delete from table_name
where (name, id) not in (select 'john', 1 union select 'sally', 2);
Actually, no I retract my comment about needing special juice or being stuck with (AND OR'ing all your options).
Since you have a list of values of what you want to retain, dump that into a temporary table. Then do a delete against the base table for what does not exist in the temporary table (left outer join). I suck at mysql syntax or I'd cobble together your query. Psuedocode is approximate
DELETE
B
FROM
BASE B
LEFT OUTER JOIN
#RETAIN R
ON R.key1 = B.key1
AND R.key2 = B.key
WHERE
R.key1 IS NULL
The NOT EXISTS version:
DELETE
b
FROM
BaseTable b
WHERE
NOT EXISTS
( SELECT
*
FROM
RetainTable r
WHERE
(r.key1, r.key2) = (b.key1, b.key2)
)

MySQL INSERT syntax using foreign key

I've got this problem.. it's soon not problem, but i want not to use more than one query if it is possible.
i want to insert data in the table using data from another table. here's example:
i have table1:
TABLE1
id name value max_data diff
AND Here's is table2
TABLE2
id name max_data
1 nm1 8000
2 nm2 9000
3 nm3 9500
4 nm4 9600
...
While inserting i know id from table2 and i want to use name and max_data from it. Something like this:
INSERT INTO table1 (value, diff, name, max_data) VALUES (5.0, -0.3, table2.name table2.max_data) WHERE table2.id = 3
Do you mean this?
insert into table1 (value, diff, name, max_data)
select 5.0, -0.3, name, max_data
from table2
where id = 3
You can include whatever literals you want in a SELECT clause. You can also use this technique to insert multiple rows at once.

How to run a case sensative comparison on text fields Access

I am trying to run a query to remove a set of ID's from a table when they are present in a field from another table.
The problem is both ID fields are of type text and the search does not appear to be case sensitive (but I need it to be). (i.e. ABC123 is different than abc123)
I am running a query similar to Select myID from table1 where myID NOT IN (Select otherID from table2)
What modification do I need to make in my Access query to make the results case sensitive when running comparison?
Try this:
SELECT a.*
FROM table1 a LEFT JOIN table2 b
ON a.myID = b.otherID
WHERE StrComp(IIF(IsNull(b.otherID ), a.myID , b.otherID), a.myID, 0) <> 0
OR IsNull(b.otherID)