I want to insert three values or three rows for each user I have. I know I can use the following query
INSERT INTO subscriptions(id_account, subscription)
SELECT id_account, 'subscriptionVAlue' FROM unnest ('{123,456,789}'::int[]) id;
to insert one row for each id in the list.
but I want is something like this
INSERT INTO subscriptions (account_id, subscription, i18nkey)
VALUES (id, 'subscription1', 'translation1')
VALUES (id, 'subscription2', 'translation2')
VALUES (id, 'subscription3', 'translation3')
where id in (123,1234,410,4512);
This is such bad query I know, but I want similar kind of behavior. Is that possible?
You can use cross join:
INSERT INTO subscriptions (account_id, subscription, i18nkey)
SELECT a.account_id, subscription, i18nkey
FROM (SELECT 'subscription1' as subscription, 'translation1' as i18nkey UNION ALL
SELECT 'subscription2', 'translation2' UNION ALL
SELECT 'subscription3', 'translation3'
) x CROSS JOIN
(SELECT 123 as account_id UNION ALL SELECT 1234 UNION ALL
SELECT 410 UNION ALL SELECT 4512
) a;
unnest() is not MySQL syntax. You can also do something similar with unnest(). The above should work in almost any database, although you might need a FROM clause (such as FROM dual) for the subqueries.
Related
I can't seem to find a good way to select unique data. Specifically unique values within a query.
Here's an example:
A select distinct query returns 10,000 rows. Within those rows, one column - let's call it vendors - has maybe 6 unique values. How can I return just the 6 unique vendors without scrolling through 10,000 records to make sure I caught them all. Even sorting by vendor this would still be a daunting task.
select distinct vendor from (select [distinct] col1, col2, ..., vendor from your_table) temp;
On the other hand you could ask directly for the distinct vendor, without running the more expensive query:
select distinct vendor from yourtable where {your_criteria}
Maybe you shoud try to give alias to your query result that returns 10k rows
something like (SELECT DISTINCT FROM ... ) as yourtable
and then do SELECT DISTINCT your column name FROM yourtable
(SELECT DISTINCT * FROM xxx ) as yourtable // this would return your 10k rows and nam that table simply yourtable
and then SELECT DISTINCT youruniquecolumn FROM yourtable // this will select all unique columns from your 10k table
I use this query to insert multiple rows into my table user.
insert into user
(select 'bbb', coalesce(max(subid),0)+1 from user where name = 'bbb')
union
(select 'ccc', coalesce(max(subid),0)+1 from user where name = 'ccc');
How can I achieve the same result in a single select query?
Not quite. The problem is what happens when the names are not in the table. You can do this:
insert into user(name, subid)
select n.name, coalesce(max(u.subid), 1)
from (select 'bbb' as name union all select 'ccc') n left join
user u
on u.name = n.name
group by u.name;
It still has a union (all) for constructing the names, but the calculation of subid is only expressed once.
When using insert it is a good idea to list the columns explicitly.
I have a table of users:
UserID | User
1 Martin
2 Lilian
3 Oliver
Now I have another table:
dataID | UserID | key | value
Now what I need to do is:
Select certain users from the user-table and insert several recrods in the data-table:
I need to combine these two querys:
INSERT INTO `data` (`UserID`, `key`, `value`)
VALUES (HERE_ID_OF_USER, 'someKey', 10),
VALUES (HERE_ID_OF_USER, 'otherKey', 20)
SELECT `UserID` FROM `users` WHERE ...
Not sure I fully understand what you want to do, but I'll assume you want this:
INSERT INTO data (UserID,key,value) SELECT UserID,'somekey',10 FROM users WHERE ...
INSERT INTO data (UserID,key,value) SELECT UserID,'otherkey',20 FROM users WHERE ...
If that's not what you want, you'll need to be a bit more explicit...
Update
If you already have the data you want to insert for each user in a table, you can use:
INSERT INTO data (UserID,key,value)
SELECT u.UserID,dd.key,dd.value FROM users u,default_data dd WHERE ...
If you don't (and don't want to store it in a table), you can use;
INSERT INTO data (UserID,key,value)
SELECT UserID,'some key',10 FROM users WHERE ...
UNION ALL
SELECT UserID,'other key',20 FROM users WHERE ...
or (to avoid the repetition of the WHERE clause):
INSERT INTO data (UserId,key,value)
SELECT u.UserID,dd.key,dd.value
FROM users u,
(
SELECT 'some key' AS key,10 AS data
UNION ALL
SELECT 'other key',20
) dd
WHERE ...
There are probably more ways to do it.
Build your select query to fetch data from 2 table based on User ID join. Then insert the result set into the desired table.
INSERT INTO DATA (SELECT A.USER_ID, B.KEY, B.VALUE FROM USERS A, SECOND_TABLE B WHERE A.USER_ID = B.USER_ID AND A.USER_ID IN (.....))
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
I have a table that has training history that has been modified by many different users over the years. This has cause the same training record to be entered twice. I want to create a table that replicates the main table and insert all duplicate records.
What constitutes a duplicate record is if the employee_id, course_code, and completion_date all match.
I can create the duplicate table and I have a select statement that appears to pull duplicates, but it pulls only one of them and I need it to pull both (or more) of them. This is because one person may have entered the training record with a different course name but the id, code, and date are the same so it is a duplicate entry. So by pulling all the duplicates I can validate that that is the case.
Here is my SELECT statement:
SELECT *
FROM
training_table p1
JOIN
training_table p2 ON (
p1.employee_id = p2.employee_id
AND p1.course_code = p2.course_code
AND p1.completion.date = p2.completion_date)
GROUP BY p1.ssn;
The query runs and returns what appear to be unique rows. I would like all of the duplicates. And whenever I try to INSERT it into an identical table I get an error stating my column count doesn't match my value count.
Any help would be great.
This will select any duplicate rows for insertion into your new table.
SELECT p1.*
FROM training_table p1
JOIN
(SELECT employee_id, course_code, completion_date
FROM training_table
GROUP BY employee_id, course_code, completion_date
HAVING COUNT(*) > 1
) dups
ON p1.employee_id = dups.employee_id
AND p1.course_code = dups.course_code
AND p1.completion_date = dups.completion_date
;
Try to use CROSS JOIN (Cartesian Product Join) instead JOIN only. For insert try INSERT INTO TABLE (column1, column2, column3) SELECT column1, column2, column3 FROM TABLE; in same order.
Thanks for the help. I had discovered the answer shortly after I posted the question (even though I had looked for the answer for over an hour :) ) Here is what I used:
SELECT *
FROM training_table mto
WHERE EXISTS
(
SELECT 1
FROM training_table mti
WHERE mti.employee_id = mto.employee_ie
AND mti.course_code = mto.course_code
AND mti.completion_date = mto.completion_date
LIMIT 1, 1
)
I just added the INSERT statement and it worked.
Thanks.