Insert statement with multiple Select statements in SQL Server - sql-server-2008

I have a query to insert some records using multiple Select statements
My query is as follows
INSERT INTO tbl_StreetMaster
(
StreetName,
CityID,
StartPoint,
EndPoint,
StoreID,
IsActive,
CreationDate,
CreatedBy
)
SELECT
(SELECT a.StreetName,CAST(a.CityName AS INT),a.EndPointFrom,a.EndPointTo
FROM #TempRecords a
WHERE NOT EXISTS
(SELECT b.StreetID,b.StreetName FROM tbl_StreetMaster b
WHERE a.StreetName=b.StreetName and a.EndPointFrom=b.StartPoint and
a.EndPointTo=b.EndPoint and CAST(a.CityName AS INT)=b.CityID and b.IsActive=1
))
,
(SELECT a.StoreID FROM tbl_StoreGridMapping a
inner join tbl_GridMaster b on a.GridID=b.GridID
inner join #TempRecords c on b.GridCode=c.GridCode1
WHERE NOT EXISTS
(SELECT b.StreetID,b.StreetName FROM tbl_StreetMaster b
WHERE c.StreetName=b.StreetName and c.EndPointFrom=b.StartPoint and
c.EndPointTo=b.EndPoint and CAST(c.CityName AS INT)=b.CityID and b.IsActive=1))
,
1,GETDATE(),100
Even though I have right number of columns in my Select it gives me error all the time
The select list for the INSERT statement contains fewer items
than the insert list. The number of SELECT values must match the number of INSERT
columns.
Can any one help out with this.

You can't return multiple columns from a subselect (so the system is probably assuming one column from each subselect and counting five columns total, and not getting far enough to tell you that the subselects can only return 1 value.
I'm not clear why you haven't written it as a single query anyway:
INSERT INTO tbl_StreetMaster
(
StreetName,
CityID,
StartPoint,
EndPoint,
StoreID,
IsActive,
CreationDate,
CreatedBy
)
SELECT
c.StreetName,CAST(c.CityName AS INT),c.EndPointFrom,c.EndPointTo,
a.StoreID, 1,GETDATE(),100
FROM tbl_StoreGridMapping a
inner join tbl_GridMaster b on a.GridID=b.GridID
inner join #TempRecords c on b.GridCode=c.GridCode1
WHERE NOT EXISTS
(SELECT b.StreetID,b.StreetName FROM tbl_StreetMaster b
WHERE c.StreetName=b.StreetName and c.EndPointFrom=b.StartPoint and
c.EndPointTo=b.EndPoint and CAST(c.CityName AS INT)=b.CityID and b.IsActive=1)
Unless the mapping through tbl_GridMaster and tbl_StoreGridMapping may not exist (and you want a null for StoreID, in which case you might want to replace the inner joins with right joins.
I'd also query the wisdom (somewhere along the line) of casting a column called CityName to an INT. Something's broken there (in naming, if nothing else).

You can do it if you put a union bewteen selects
like this:
INSERT INTO table(elem1,elem2,elem3) SELECT elem1,elem2,elem3 from table1 union select elem1,elem2,elem3 from table2 union select elem1,elem2,elem3 from table3

Related

Select column from selected column subquery [duplicate]

I am running this query on MySQL
SELECT ID FROM (
SELECT ID, msisdn
FROM (
SELECT * FROM TT2
)
);
and it is giving this error:
Every derived table must have its own alias.
What's causing this error?
Every derived table (AKA sub-query) must indeed have an alias. I.e. each query in brackets must be given an alias (AS whatever), which can the be used to refer to it in the rest of the outer query.
SELECT ID FROM (
SELECT ID, msisdn FROM (
SELECT * FROM TT2
) AS T
) AS T
In your case, of course, the entire query could be replaced with:
SELECT ID FROM TT2
I think it's asking you to do this:
SELECT ID
FROM (SELECT ID,
msisdn
FROM (SELECT * FROM TT2) as myalias
) as anotheralias;
But why would you write this query in the first place?
Here's a different example that can't be rewritten without aliases ( can't GROUP BY DISTINCT).
Imagine a table called purchases that records purchases made by customers at stores, i.e. it's a many to many table and the software needs to know which customers have made purchases at more than one store:
SELECT DISTINCT customer_id, SUM(1)
FROM ( SELECT DISTINCT customer_id, store_id FROM purchases)
GROUP BY customer_id HAVING 1 < SUM(1);
..will break with the error Every derived table must have its own alias. To fix:
SELECT DISTINCT customer_id, SUM(1)
FROM ( SELECT DISTINCT customer_id, store_id FROM purchases) AS custom
GROUP BY customer_id HAVING 1 < SUM(1);
( Note the AS custom alias).
I arrived here because I thought I should check in SO if there are adequate answers, after a syntax error that gave me this error, or if I could possibly post an answer myself.
OK, the answers here explain what this error is, so not much more to say, but nevertheless I will give my 2 cents, using my own words:
This error is caused by the fact that you basically generate a new table with your subquery for the FROM command.
That's what a derived table is, and as such, it needs to have an alias (actually a name reference to it).
Given the following hypothetical query:
SELECT id, key1
FROM (
SELECT t1.ID id, t2.key1 key1, t2.key2 key2, t2.key3 key3
FROM table1 t1
LEFT JOIN table2 t2 ON t1.id = t2.id
WHERE t2.key3 = 'some-value'
) AS tt
At the end, the whole subquery inside the FROM command will produce the table that is aliased as tt and it will have the following columns id, key1, key2, key3.
Then, with the initial SELECT, we finally select the id and key1 from that generated table (tt).

How to use AVG() function after GROUP BY with CASE in MySQL [duplicate]

I am running this query on MySQL
SELECT ID FROM (
SELECT ID, msisdn
FROM (
SELECT * FROM TT2
)
);
and it is giving this error:
Every derived table must have its own alias.
What's causing this error?
Every derived table (AKA sub-query) must indeed have an alias. I.e. each query in brackets must be given an alias (AS whatever), which can the be used to refer to it in the rest of the outer query.
SELECT ID FROM (
SELECT ID, msisdn FROM (
SELECT * FROM TT2
) AS T
) AS T
In your case, of course, the entire query could be replaced with:
SELECT ID FROM TT2
I think it's asking you to do this:
SELECT ID
FROM (SELECT ID,
msisdn
FROM (SELECT * FROM TT2) as myalias
) as anotheralias;
But why would you write this query in the first place?
Here's a different example that can't be rewritten without aliases ( can't GROUP BY DISTINCT).
Imagine a table called purchases that records purchases made by customers at stores, i.e. it's a many to many table and the software needs to know which customers have made purchases at more than one store:
SELECT DISTINCT customer_id, SUM(1)
FROM ( SELECT DISTINCT customer_id, store_id FROM purchases)
GROUP BY customer_id HAVING 1 < SUM(1);
..will break with the error Every derived table must have its own alias. To fix:
SELECT DISTINCT customer_id, SUM(1)
FROM ( SELECT DISTINCT customer_id, store_id FROM purchases) AS custom
GROUP BY customer_id HAVING 1 < SUM(1);
( Note the AS custom alias).
I arrived here because I thought I should check in SO if there are adequate answers, after a syntax error that gave me this error, or if I could possibly post an answer myself.
OK, the answers here explain what this error is, so not much more to say, but nevertheless I will give my 2 cents, using my own words:
This error is caused by the fact that you basically generate a new table with your subquery for the FROM command.
That's what a derived table is, and as such, it needs to have an alias (actually a name reference to it).
Given the following hypothetical query:
SELECT id, key1
FROM (
SELECT t1.ID id, t2.key1 key1, t2.key2 key2, t2.key3 key3
FROM table1 t1
LEFT JOIN table2 t2 ON t1.id = t2.id
WHERE t2.key3 = 'some-value'
) AS tt
At the end, the whole subquery inside the FROM command will produce the table that is aliased as tt and it will have the following columns id, key1, key2, key3.
Then, with the initial SELECT, we finally select the id and key1 from that generated table (tt).

MySQL SELECT in SELECT-clause or in WHERE-clause in order to filter further

I'm trying to filter some data, but as the data comes from 2 tables in the database I have to union them together, permitting nulls from the second table as I always need to have any values available in the first table, due to this being a product database with some products having sub-combinations and some none. Thus far I've come up with using a Union to join the two tables together, but now I need a method to filter out the data using a WHERE clause; however: this is where I get stuck. I tried putting the union as a select statement in the FROM clause: no data returned, I tried to put it into the SELECT clause as a sub: no data returned...
In short I need something like this:
SELECT id_product, id_product_attribute,upc1,upc2
FROM (UNION)
WHERE upc1='xyz' OR upc2='xyz';
where for example the result might be things such as:
-> 100, null, 9912456, null
or
-> 200, 153, 9915559, 9977123
Currently I have this (sorry I don't have more):
(SELECT product.id_product as id_product,
product.upc as upc1,
comb.id_product_attribute,
comb.upc as upc2
FROM `db`.table1 product
LEFT JOIN `db`.table2 comb
ON comb.id_product = product.id_product
)
UNION
(SELECT product.id_product as id_product,
product.upc as headCNK,
comb.id_product_attribute,
comb.upc
FROM `db`.table1 product
RIGHT JOIN `db`.table2 comb
ON comb.id_product = product.id_product
);
Also note that upc1 is coming from table 1, and upc2 from table2.
I could use the entire query, and filter out everything using some business logic in the worst case scenario, but rather not as I don't want to perform endless queries where I don't have to, my service provider doesn't like that...
UPDATE:
I also tried:
SELECT *
from db.t1 as prod
CROSS JOIN db.t2 as comb ON prod.id_product = comb.id_product
WHERE prod.upc = 'xyz' OR comb.upc = 'xyz';
This didn't work either.
Placed a fiddle here with some small sample data:
http://sqlfiddle.com/#!9/340d7d
The output for the '991002' used in the where clause in query SELECT id_product, id_product_attribute, table1.upc, table2.upc should be: 101, null, 991002, null
And for '990001' it should then be: 101, 201, 990001, 990001
For all values try
SELECT t1.id_product, t2.id_product_attribute, t1.upc, t2.upc
FROM ( SELECT upc FROM table1
UNION
SELECT upc FROM table2 ) t0
LEFT JOIN table1 t1 USING (upc)
LEFT JOIN table2 t2 USING (upc)
For definite upc value edit to
...
SELECT t1.id_product, t2.id_product_attribute, t1.upc, t2.upc
FROM ( SELECT 990001 upc ) t0
LEFT JOIN table1 t1 USING (upc)
LEFT JOIN table2 t2 USING (upc)
...

Error when I delcare my own variable in MySQL [duplicate]

I am running this query on MySQL
SELECT ID FROM (
SELECT ID, msisdn
FROM (
SELECT * FROM TT2
)
);
and it is giving this error:
Every derived table must have its own alias.
What's causing this error?
Every derived table (AKA sub-query) must indeed have an alias. I.e. each query in brackets must be given an alias (AS whatever), which can the be used to refer to it in the rest of the outer query.
SELECT ID FROM (
SELECT ID, msisdn FROM (
SELECT * FROM TT2
) AS T
) AS T
In your case, of course, the entire query could be replaced with:
SELECT ID FROM TT2
I think it's asking you to do this:
SELECT ID
FROM (SELECT ID,
msisdn
FROM (SELECT * FROM TT2) as myalias
) as anotheralias;
But why would you write this query in the first place?
Here's a different example that can't be rewritten without aliases ( can't GROUP BY DISTINCT).
Imagine a table called purchases that records purchases made by customers at stores, i.e. it's a many to many table and the software needs to know which customers have made purchases at more than one store:
SELECT DISTINCT customer_id, SUM(1)
FROM ( SELECT DISTINCT customer_id, store_id FROM purchases)
GROUP BY customer_id HAVING 1 < SUM(1);
..will break with the error Every derived table must have its own alias. To fix:
SELECT DISTINCT customer_id, SUM(1)
FROM ( SELECT DISTINCT customer_id, store_id FROM purchases) AS custom
GROUP BY customer_id HAVING 1 < SUM(1);
( Note the AS custom alias).
I arrived here because I thought I should check in SO if there are adequate answers, after a syntax error that gave me this error, or if I could possibly post an answer myself.
OK, the answers here explain what this error is, so not much more to say, but nevertheless I will give my 2 cents, using my own words:
This error is caused by the fact that you basically generate a new table with your subquery for the FROM command.
That's what a derived table is, and as such, it needs to have an alias (actually a name reference to it).
Given the following hypothetical query:
SELECT id, key1
FROM (
SELECT t1.ID id, t2.key1 key1, t2.key2 key2, t2.key3 key3
FROM table1 t1
LEFT JOIN table2 t2 ON t1.id = t2.id
WHERE t2.key3 = 'some-value'
) AS tt
At the end, the whole subquery inside the FROM command will produce the table that is aliased as tt and it will have the following columns id, key1, key2, key3.
Then, with the initial SELECT, we finally select the id and key1 from that generated table (tt).

SQL Join 2 tables with almost same field

I need to join two tables in SQL. There are no common fields. But the one table have a field with the value krin1001 and I need it to be joined with the row in the other table where the value is 1001.
The idea behind the joining is i have multiple customers, but in the one table there customer id is 'krin1001' 'krin1002' and so on, in this table is how much they have sold. In the other table there customer is is '1001' '1002' and so on, and in this table is there name and adress and so on. So it will always be the first 4 charakters i need to strip from the field before matching and joining. It might not always be 'krin' i need it to work with 'khjo1001' also, and it still needs to join on the '1001' value from the other table.
Is that possible?
Hope you can help me.
You need to use substring:
ON SUBSTRING(TableA.Field, 5, 4) = TableB.Field
Or Right:
ON RIGHT(TableA.Field, 4) = TableB.Field
You can also try to use CHARINDEX function for join operation. If value from table1 contains value from table2 row will be included in result set.
;WITH table1 AS(
SELECT 'krin1001' AS val
UNION ALL
SELECT 'xxx'
UNION ALL
SELECT 'xyz123'
),
table2 AS(
SELECT '1001' AS val
UNION ALL
SELECT '12345'
UNION ALL
SELECT '123'
)
SELECT * FROM table1 AS t
JOIN table2 AS T2 ON CHARINDEX(T2.val, T.val) > 0
Use it as:
SELECT
*
FROM table t1
INNER JOIN table t2 ON RIGHT(t1.col1, 4) = t2.col1;