SQL - Insert two columns, one from a table, the other constant - sql

I have a many to many relation table in which I need to insert rows.
Suppose the headers Are:
Table1: Id_1 | Etc....
Table2: Id_2 | Etc....
Relation_Table: Id_1 | Id_2 | Etc.
I need to do the following:
Insert a new element in table 1
Link this new element to all elements in table 2
So, I need to add in the relation table, n rows as the following:
(id_1_new, id_2_0),
(id_1_new, id_2_1),
(id_1_new, id_2_2),
(id_1_new, id_2_3),
(id_1_new, id_2_4),
(id_1_new, id_2_5),
(id_1_new, id_2_6),....
Where id_1_new is known and may be entered manually
And id_2_n may come from select Id_2 from Table2.
How can I do this using SQL statements?
Microsoft Access solutions are welcome as well.

you can use insert... select syntax in order to select the data from the second table to your relation table, using the new id as const in the select :
insert into Relation_table (Id_1, Id_2)
select 'id_1_new' as Id_1, Id_2 from Table2;

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

How can I remove duplicate rows from a table but keeping the summation of values of a column

Suppose there is a table which has several identical rows. I can copy the distinct values by
SELECT DISTINCT * INTO DESTINATIONTABLE FROM SOURCETABLE
but if the table has a column named value and for the sake of simplicity its value is 1 for one particular item in that table. Now that row has another 9 duplicates. So the summation of the value column for that particular item is 10. Now I want to remove the 9 duplicates(or copy the distinct value as I mentioned) and for that item now the value should show 10 and not 1. How can this be achieved?
item| value
----+----------------
A | 1
A | 1
A | 1
A | 1
B | 1
B | 1
I want to show this as below
item| value
----+----------------
A | 4
B | 2
Thanks in advance
You can try to use SUM and group by
SELECT item,SUM(value) value
FROM T
GROUP BY item
SQLfiddle:http://sqlfiddle.com/#!18/fac26/1
[Results]:
| item | value |
|------|-------|
| A | 4 |
| B | 2 |
Broadly speaking, you can just us a sum and a GROUP BY clause.
Something like:
SELECT column1, SUM(column2) AS Count
FROM SOURCETABLE
GROUP BY column1
Here it is in action: Sum + Group By
Since your table probably isn't just two columns of data, here is a slightly more complex example showing how to do this to a larger table: SQL Fiddle
Note that I've selected my rows individually so that I can access the necessary data, rather than using
SELECT *
And I have achieved this result without the need for selecting data into another table.
EDIT 2:
Further to your comments, it sounds like you want to alter the actual data in your table rather than just querying it. There may be a more elegant way to do this, but a simple way use the above query to populate a temporary table, delete the contents of the existing table, then move all the data back. To do this in my existing example:
WITH MyQuery AS (
SELECT name, type, colour, price, SUM(number) AS number
FROM MyTable
GROUP BY name, type, colour, price
)
SELECT * INTO MyTable2 FROM MyQuery;
DELETE FROM MyTable;
INSERT INTO MyTable(name, type, colour, price, number)
SELECT * FROM MyTable2;
DROP TABLE MyTable2;
WARNING: If youre going to try this, please use a development environment first (i.e one you don't mind breaking!) to ensure it does exactly what you want it to do. It's imperative that your initial query captures ALL the data you want.
Here is the SQL Fiddle of this example in action: SQL Fiddle

SQL Multiple Row Insert w/ multiple selects from different tables

I am trying to do a multiple insert based on values that I am pulling from a another table. Basically I need to give all existing users access to a service that previously had access to a different one. Table1 will take the data and run a job to do this.
INSERT INTO Table1 (id, serv_id, clnt_alias_id, serv_cat_rqst_stat)
SELECT
(SELECT Max(id) + 1
FROM Table1 ),
'33', --The new service id
clnt_alias_id,
'PI' --The code to let the job know to grant access
FROM TABLE2,
WHERE serv_id = '11' --The old service id
I am getting a Primary key constraint error on id.
Please help.
Thanks,
Colin
This query is impossible. The max(id) sub-select will evaluate only ONCE and return the same value for all rows in the parent query:
MariaDB [test]> create table foo (x int);
MariaDB [test]> insert into foo values (1), (2), (3);
MariaDB [test]> select *, (select max(x)+1 from foo) from foo;
+------+----------------------------+
| x | (select max(x)+1 from foo) |
+------+----------------------------+
| 1 | 4 |
| 2 | 4 |
| 3 | 4 |
+------+----------------------------+
3 rows in set (0.04 sec)
You will have to run your query multiple times, once for each record you're trying to copy. That way the max(id) will get the ID from the previous query.
Is there a requirement that Table1.id be incremental ints? If not, just add the clnt_alias_id to Max(id). This is a nasty workaround though, and you should really try to get that column's type changed to auto_increment, like Marc B suggested.

SQL Show duplicate records only once in a result set

Is it possible in SQL to show duplicate records in a result only once.
So instead of this
my#email.com | Some Unique Data | Unique Data
my#email.com | Some Unique Data | Unique Data
my#email.com | Some Unique Data | Unique Data
my#email.com | Some Unique Data | Unique Data
I would get this
my#email.com | Some Unique Data | Unique Data
| Some Unique Data | Unique Data
| Some Unique Data | Unique Data
You should not be using SQL to perform presentational tasks. Any solution to do so is going to be very hacky and require cursors / some other iterative approach.
Almost every report authoring tool has a way to hide duplicates.
simply you can do this --
there are so many option or answer available for this.
one of these is as follow--
select
case
when b.c_1 = 1 then
b.col1
else
null
end col1,
b.col2 col2,
b.col3 col3
from
(
select distinct col1,col2,col3, rownum() over(partition by col1) c_1 from table_name
)b
now assume / modify above query -
table_name is the table name
col1 , col2 and col3 is your table's column name.
just modify this query as per your table name and structure and see..
it would be your required solution.
I know that this is an old question but thought this might be of use to other people. After researching this for awhile, there is a keyword called DISTINCT that will show duplicate values in a query only once. I was using a query to auto-suggest values in a text box on a web page and didn't want it to show duplicate names and this worked for me:
SELECT DISTINCT FIRSTNAME
FROM TBLSTUDENTS
WHERE FIRSTNAME LIKE '#ucase(arguments.search)#%'

I DISTINCTly hate MySQL (help building a query)

This is staight forward I believe:
I have a table with 30,000 rows. When I SELECT DISTINCT 'location' FROM myTable it returns 21,000 rows, about what I'd expect, but it only returns that one column.
What I want is to move those to a new table, but the whole row for each match.
My best guess is something like SELECT * from (SELECT DISTINCT 'location' FROM myTable) or something like that, but it says I have a vague syntax error.
Is there a good way to grab the rest of each DISTINCT row and move it to a new table all in one go?
SELECT * FROM myTable GROUP BY `location`
or if you want to move to another table
CREATE TABLE foo AS SELECT * FROM myTable GROUP BY `location`
Distinct means for the entire row returned. So you can simply use
SELECT DISTINCT * FROM myTable GROUP BY 'location'
Using Distinct on a single column doesn't make a lot of sense. Let's say I have the following simple set
-id- -location-
1 store
2 store
3 home
if there were some sort of query that returned all columns, but just distinct on location, which row would be returned? 1 or 2? Should it just pick one at random? Because of this, DISTINCT works for all columns in the result set returned.
Well, first you need to decide what you really want returned.
The problem is that, presumably, for some of the location values in your table there are different values in the other columns even when the location value is the same:
Location OtherCol StillOtherCol
Place1 1 Fred
Place1 89 Fred
Place1 1 Joe
In that case, which of the three rows do you want to select? When you talk about a DISTINCT Location, you're condensing those three rows of different data into a single row, there's no meaning to moving the original rows from the original table into a new table since those original rows no longer exist in your DISTINCT result set. (If all the other columns are always the same for a given Location, your problem is easier: Just SELECT DISTINCT * FROM YourTable).
If you don't care which values come from the other columns you can use a (bad, IMHO) MySQL extension to SQL and do:
SELECT * FROM YourTable GROUP BY Location
which will give a result set with one row per location and values for the other columns derived from the original data in an undefined fashion.
Multiple rows with identical values in all columns don't have any sense. OK - the question might be a way to correct exactly that situation.
Considering this table, with id being the PK:
kram=# select * from foba;
id | no | name
----+----+---------------
2 | 1 | a
3 | 1 | b
4 | 2 | c
5 | 2 | a,b,c,d,e,f,g
you may extract a sample for every single no (:=location) by grouping over that column, and selecting the row with minimum PK (for example):
SELECT * FROM foba WHERE id IN (SELECT min (id) FROM foba GROUP BY no);
id | no | name
----+----+------
2 | 1 | a
4 | 2 | c