I want to insert records from Table1 and Table2 into Table3 and my Table3 has Two columns:
studentId
subjectId
And I want to insert these 2 values from Table1(contains 1000 student Id's) and From Table2(contains 5 subjects). To achieve that I have used following query but it gave me error
Query:
INSERT INTO StudentSubject(studentId,subjectId)
SELECT studentId FROM Table1 UNION SELECT subjectId FROM Table2
But I got this error message:
Msg 120, Level 15, State 1, Line 1
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.
INSERT into StudentSubject(studentId,subjectId)
SELECT a.studentId,b.subjectId
FROM Table1 a CROSS JOIN Table2 b
Related
I have 2 table and second table use relationship
table1
id name
---------
1 alpha
2 beta
table2
id name relation
-------------------
1 2015 2
2 2016 2
3 2017 2
4 2018 2
I want to see
name data
-------------------------
beta 2015,2016,2017,2018
alpha NULL
I tried the following sql query but the output is not what I wanted
I use:
SELECT
t1.name,
GROUP_CONCAT(t2.name SEPARATOR ',')
FROM table1 AS t1
LEFT JOIN table2 AS t2
ON t2.relation = t1.id
Output:
alpha 2015,2016,2017,2018
Alpha doesn't get any value in the other related tablature. the values in the output belong to the beta.
You need GROUP BY:
SELECT t1.name,
GROUP_CONCAT(t2.name SEPARATOR ',')
FROM table1 t1 LEFT JOIN
table2 t2
ON t2.relation = t1.id
GROUP BY t1.name;
In most databases (and recent versions of MySQL), your query would fail. It is an aggregation query (because of the GROUP_CONCAT()). But, t1.name is not an argument to an aggregation function and it is not a GROUP BY key.
MySQL does allow this type of query. It returns exactly one row. The value of t1.name on the one row in the result set comes from an arbitrary row.
No FKs for fiddle:
CREATE TABLE Table1 (`id` int, `name` varchar(5)) ;
INSERT INTO Table1
(`id`, `name`)
VALUES
(1, 'alpha'),
(2, 'beta')
;
CREATE TABLE Table2 (`id` int, `name` int, `relation` int);
INSERT INTO Table2
(`id`, `name`, `relation`)
VALUES
(1, 2015, 2),
(2, 2016, 2),
(3, 2017, 2),
(4, 2018, 2)
;
Statement:
SELECT
t1.name,
GROUP_CONCAT(t2.name SEPARATOR ',') -- missing an AS .... => ugly name from fiddle
FROM table1 AS t1
LEFT JOIN table2 AS t2
ON t2.relation = t1.id
group by t1.name
Output:
name GROUP_CONCAT(t2.name SEPARATOR ',')
alpha (null)
beta 2017,2018,2015,2016
I want to have results in a table where the data comes from 3 different tables.
For that I have tried to execute this query:
INSERT INTO sometable (id,date)
VALUES
(
(SELECT id FROM table1
UNION
SELECT id FROM table2
UNION
SELECT id FROM table3)
,
(SELECT date FROM table1
UNION
SELECT date FROM table2
UNION
SELECT date FROM table3)
)
The result of this query is an error stating cannot insert multiple rows. Please help me to write this query correctly.
The INSERT ... SELECT syntax is different to the INSERT ... VALUES syntax. Also, you want to select both columns from each table at the same time:
INSERT INTO sometable (id, date)
SELECT id, date FROM table1 UNION
SELECT id, date FROM table2 UNION
SELECT id, date FROM table3
Im trying to optimize an INSERT INTO statement to use a subquery only once, as it is always the same value:
Heres my example code
INSERT INTO TABLE1 (id, number) VALUES
((SELECT other_id from TABLE2 WHERE somevalue = "test"), 12),
((SELECT other_id from TABLE2 WHERE somevalue = "test"), 13),
...,
...;
Not an sql-expert, but this doesnt look like a good approach, as the same subquery gets executed on every insert.
Is there an alternative solution?
also, i know i can select the ID beforehand and store it in a variable like this (pseudo-code-like):
$var = mysql_query("SELECT other_id from TABLE2 WHERE somevalue = 'test'")
mysql_query("INSERT INTO TABLE1 (id, number) VALUES
($var, 12),
($var, 13);")
INSERT
INTO table1 (id, number)
SELECT other_id, number
FROM table2
CROSS JOIN
(
SELECT 12 number
UNION ALL
SELECT 13
) q
WHERE somevalue = 'test'
What is the easiest way to select all records via JOIN on a column, and returning the values that they do not share, i.e. are unique to each table's column?
What I'm looking for is something similar to PHP's array_diff();
So if the table columns contain the following values:
Table 1 column values: 1, 45, 7, 99, 31
Table 2 column values: 100, 3, 7, 31, 22
Results should give me the following values back: 1, 45, 99, 100, 3, 31, 22 (i.e. skip the mutual values 7 and 31).
This is based on the text "returning the values that they do not share, i.e. are unique to each table's column?".
There are several way to approach this. Perhaps the most obvious is to take everything from the first table not in the second and vice versa:
select value
from table1
where not exists (select 1 from table2 where table2.value = table1.value)
union all
select value
from table2
where not exists (select 1 from table1 where table2.value = table1.value);
If you don't have duplicates in either table, then another approach is to union the tables together and then return the ones that only appear once:
select value
from (select value from table1 union all
select value from table2
) t
group by value
having count(*) = 1;
EDIT:
The equivalent of array_diff is simply:
select value
from table1
where not exists (select 1 from table2 where table2.value = table1.value)
It is not symmetric.
Use NOT IN.
SELECT id FROM table1 WHERE id NOT IN (SELECT id FROM table2)
I need to compare the final balances of two tables from different clients grouped by ID. The tables have the same ID's But one has multiple ID entries and the other does not. I need to sum row from the table with multiple entries so I have just one final number to do calculations with.
Table1:
ID, cost, traceNumber, TheDate
1, 200, 1001, 10/07/2011
1, -20, 1002, 10/08/2011
1, 130, 1003, 10/10/2011
2, 300, 1005, 10/10/2011
Table2:
ID, cost
1, 200
2, 300
Result for ID 1, would be 310 compared to table2 of 200 with a difference of 110
The Query will look something like this.
SELECT DISTINCT
Table1.ID,
Table1.TheDate ,
Table1.traceNumber,
Table1.[cost] AS Frost_Balance,
SUM(Table1.[cost]) AS SUM_Frost_Balance,
Table2.[cost] AS Ternean_Balance,
SUM(Table1.[cost]) - Table2.[cost] AS Ending_Balance,
FROM
Table1
INNER JOIN Table2 ON Table1.ID =Table2.CustomerID
GROUP BY
dbo.Frost.ID
The query has to display multiple columns in the result set because it is going to be used to report on. I tried grouping by all columns in the result set but that gave me wrong results. Is there another way to compute the column that needs to be summed up?
You can use a "Window Aggregate Function" like this:
select
table1.*,
sum(table1.cost) over (partition by table1.id) sum_frost_balance,
table2.cost,
sum(table1.cost) over (partition by table1.id) - table2.cost ending_balance
from table1
join table2 on table1.id = table2.id
Is this what you're trying to do?
-- Data setup
CREATE TABLE [Table1]
(
[ID] INT,
[cost] INT,
[traceNumber] INT,
[TheDate] DATE
)
INSERT [Table1]
VALUES (1, 200, 1001, '10/07/2011'),
(1, -20, 1002, '10/08/2011'),
(1, 130, 1003, '10/10/2011'),
(2, 300, 1005, '10/10/2011')
CREATE TABLE [Table2]
(
[ID] INT,
[cost] INT
)
INSERT [Table2]
VALUES (1, 200),
(2, 300)
-- Query
;WITH [cteTable1Sum] AS
(
SELECT [ID], SUM([cost]) AS [cost]
FROM [Table1]
GROUP BY [ID]
)
SELECT [Table1].[ID],
[Table1].[TheDate],
[Table1].[traceNumber],
[Table1].[cost] AS [Frost_Balance],
cte.[cost] AS [SUM_Frost_Balance],
[Table2].[cost] AS [Ternean_Balance],
cte.[cost] - [Table2].[cost] AS [Ending_Balance]
FROM [Table1]
INNER JOIN [Table2]
ON [Table1].[ID] = [Table2].[ID]
INNER JOIN [cteTable1Sum] cte
ON [Table1].[ID] = cte.[ID]