it had been a while since i used sql,
need a little push...
got 2 table, users and votes
users {id,email....}
votes {id,userid,date,vote}
the sql:
INSERT INTO votes_table (users_table.id , date,vote)
VALUES (
(SELECT users_table.id, users_table.email
FROM users_table
WHERE users_table.email='lalala#lalall.com')
,datetime
,true
)
the error
Error Code: 1241. Operand should contain 1 column(s)
Your inner query is selecting 2 columns. Change this to just return the id:
INSERT INTO votes_table (users_table.id , date,vote)
VALUES (
(SELECT users_table.id
FROM users_table
WHERE users_table.email='lalala#lalall.com')
,datetime
,true
)
Try this, you are returning more number of columns in your sub-query, you can simply your query to this
INSERT INTO votes_table (users_table.id , date,vote)
SELECT users_table.id,datetime, true
FROM users_table
WHERE users_table.email='lalala#lalall.com'
Related
This question already has an answer here:
PostgreSQL, SQL state: 42601
(1 answer)
Closed 3 years ago.
I have a query, that I want to make, it is an INSERT FROM a SELECT GROUP BY, but I get the error:
ERROR: INSERT has more target columns than expressions
LINE 15: INSERT INTO "KPI_MEASURE" (id, created_at, kpi_project_id, k...
_____________________________________^
HINT: The insertion source is a row expression containing the same number of columns expected by the INSERT. Did you accidentally use extra parentheses?
I've searched this error, but what I found is that, this error happen, if the number of rows doesn't match, but for the query below, there is the same number of row.
Postgres SQL query:
INSERT INTO "KPI_MEASURE" (
id,
created_at,
kpi_project_id,
kpi_frequency_id,
kpi_metric_id,
branch,
value
)
SELECT (
nextval('"KPI_MEASURE_ID_seq"'::regclass),
now(),
kpi_project.id,
kpi_measure.kpi_frequency_id,
kpi_metric.id ,
kpi_measure.branch ,
sum(kpi_measure.value)
)
FROM "KPI_MEASURE" kpi_measure
INNER JOIN "KPI_METRIC" kpi_metric ON kpi_measure.kpi_metric_id = kpi_metric.id
INNER JOIN "KPI_PROJECT" kpi_project ON kpi_measure.kpi_project_id = kpi_project.id
INNER JOIN "KPI_AGGREGATION_PROJECT" kpi_agg_project ON kpi_project.name = kpi_agg_project.child_project_name
WHERE kpi_metric.aggregated = false
GROUP BY kpi_measure.branch, kpi_metric.id, kpi_project.id, kpi_project.name, kpi_frequency_id;
When you enclose expressions in parentheses, Postgres interprets the result as a tuple -- essentially a struct or record.
So, your statement:
SELECT (
nextval('"KPI_MEASURE_ID_seq"'::regclass),
now(),
kpi_project.id,
kpi_measure.kpi_frequency_id,
kpi_metric.id ,
kpi_measure.branch ,
sum(kpi_measure.value)
)
is returning one value. That value is a record.
Databases that do not support tuples would return an error.
The solution is to remove the parentheses.
As the hint says: Did you accidentally use extra parentheses?
Remove the parentheses around the selected values and the problem is solved.
INSERT INTO "KPI_MEASURE" (
id,
created_at,
kpi_project_id,
kpi_frequency_id,
kpi_metric_id,
branch,
value
)
SELECT
nextval('"KPI_MEASURE_ID_seq"'::regclass),
now(),
kpi_project.id,
kpi_measure.kpi_frequency_id,
kpi_metric.id ,
kpi_measure.branch ,
sum(kpi_measure.value)
FROM "KPI_MEASURE" kpi_measure
INNER JOIN "KPI_METRIC" kpi_metric ON kpi_measure.kpi_metric_id = kpi_metric.id
INNER JOIN "KPI_PROJECT" kpi_project ON kpi_measure.kpi_project_id = kpi_project.id
INNER JOIN "KPI_AGGREGATION_PROJECT" kpi_agg_project ON kpi_project.name = kpi_agg_project.child_project_name
WHERE kpi_metric.aggregated = false
GROUP BY kpi_measure.branch, kpi_metric.id, kpi_project.id, kpi_project.name, kpi_frequency_id;
I am trying to insert a record in an m:n table (User-Group Relation) and return the group when the user successfully joined.
But I can't manage to return the whole group after the insert.
with "group" as (
SELECT * from "group" where code = 'tohubo' LIMIT 1
)
insert into group_users__user_groups ("group_users", "user_groups")
select id from "group", 1
returning (SELECT * from "group")
With that query I currently get the error message
subquery must return only one column
I also tried to just return *, but then I only get the content of group_users__user_groups.
I also tried to add an additional Select at the end:
with "found_group" as (
SELECT * from "group" where code = 'tohubo' LIMIT 1
)
insert into group_users__user_groups ("group_users", "user_groups")
select 1, id from "found_group";
Select * from "found_group";
But then the WITH part is not defined in the second query:
Kernel error: ERROR: relation "found_group" does not exist
The returning clause can only return data that was affected by the insert.
And you can only have one "final" statement in a CTE, not an insert and a select.
But you can simply move the insert into a second cte, and then have a single SELECT at the end that returns the data that was found
with found_group as (
SELECT *
from "group"
where code = 'tohubo'
LIMIT 1
), inserted as (
insert into group_users__user_groups (group_users, user_groups)
select 1, id
from found_group
)
Select *
from found_group;
I'm looking to insert rows of data into a table from another table, normal scenario.
Here's my current SQL script,
INSERT [dbo].[X_RPT_PORTAL_REPORTLIST] (
[PORTAL_GROUP_ID],
[REPORT_DISPLAY_NAME],
[STANDARD_REPORT],
[REPORT_PACK_VERSION],
[REPORT_PATH]
)
VALUES (
(SELECT ID FROM X_RPT_REPORTINGLIST),
(SELECT REPORT_NAME FROM X_RPT_REPORTINGLIST),
(SELECT STANDARD_REPORT FROM X_RPT_REPORTINGLIST),
(SELECT REPOPT_PACK_VERSION FROM X_RPT_REPORTINGLIST),
(SELECT PATH FROM ReportServer$PORTAL.dbo.Catalog)
)
Now my error I had return from this was:
Msg 512, Level 16, State 1, Line 1
Subquery returned more than 1 value. This is not permitted when the subquery follows =, !=, <, <= , >, >= or when the subquery is used as an expression.
I had a thought this maybe incorrect, but I need some pointers on getting around this.
Any help or tips, is much appreciated.
Thank you
This issue arose because one or more of the subqueries you have used to provide the data for VALUES() have returned multiple records. The VALUES() construct is used by INSERT to insert one and only one record.
This usually arises when people use WHERE conditions such as WHERE value = (SELECT value FROM sub_table) and the subquery returns multiple records; hence is why the error message was versed as it was.
It is possible to follow an INSERT statement with a SELECT statement which returns the data that you want put into the table, so consider the following:
INSERT [dbo].[X_RPT_PORTAL_REPORTLIST] (
[PORTAL_GROUP_ID],
[REPORT_DISPLAY_NAME],
[STANDARD_REPORT],
[REPORT_PACK_VERSION],
[REPORT_PATH])
SELECT
r.ID
,r.REPORT_NAME
,r.STANDARD_REPORT
,r.REPOPT_PACK_VERSION
,c.PATH
FROM X_RPT_REPORTINGLIST r
CROSS JOIN ReportServer$PORTAL.dbo.Catalog c;
You're attempting to insert one row into a table and can therefore only have one value for each column in the row. This error means is that one or more of the SELECT statements in your VALUES() clause is returning more than one value.
Run each of the SELECT statements individually and see which of them are returning multiple rows and then constrain them with a WHERE clause where necessary until you get the single value from each of them that you want.
I think the error message is clear. You want to switch to insert . . . select. Something like this:
INSERT [dbo].[X_RPT_PORTAL_REPORTLIST] ([PORTAL_GROUP_ID], [REPORT_DISPLAY_NAME], [STANDARD_REPORT], [REPORT_PACK_VERSION], [REPORT_PATH])
SELECT rl.ID, rl.REPORT_NAME, rl.STANDARD_REPORT, rl.REPORT_PACK_VERSION,
c.PATH
FROM X_RPT_REPORTINGLIST JOIN
ReportServer$PORTAL.dbo.Catalog c
ON rl.??? = c.???;
It is unclear what the JOIN conditions are. If there is only one path, then you might want a CROSS JOIN.
Run following queries separately. Some of them will return multiple rows which causes the error. You can use WHERE/GROUP BY/PARTITION to avoid multiple rows.
SELECT ID FROM X_RPT_REPORTINGLIST
SELECT REPORT_NAME FROM X_RPT_REPORTINGLIST
SELECT STANDARD_REPORT FROM X_RPT_REPORTINGLIST
SELECT REPOPT_PACK_VERSION FROM X_RPT_REPORTINGLIST
SELECT PATH FROM ReportServer$PORTAL.dbo.Catalog
You can do it this way
INSERT [dbo].[X_RPT_PORTAL_REPORTLIST] ([PORTAL_GROUP_ID], [REPORT_DISPLAY_NAME], [STANDARD_REPORT], [REPORT_PACK_VERSION], [REPORT_PATH])
SELECT
a.ID, a.REPORT_NAME, a.STANDARD_REPORT, a.REPOPT_PACK_VERSION,
b.PATH
FROM
X_RPT_REPORTINGLIST a
JOIN
ReportServer$PORTAL.dbo.Catalog b ON XXXXXXX
Instead of XXXX you have to type the join condition for those two tables
the issue with the query is all the subqueries are returning more than 1 records.
i.e. :
(SELECT ID FROM X_RPT_REPORTINGLIST) line is returning more than 1 records, which is not permitted in INSERT statement.
you can use following code:
INSERT [dbo].[X_RPT_PORTAL_REPORTLIST]
([PORTAL_GROUP_ID], [REPORT_DISPLAY_NAME], [STANDARD_REPORT], [REPORT_PACK_VERSION], [REPORT_PATH])
VALUES (
(SELECT top 1 ID FROM X_RPT_REPORTINGLIST),
(SELECT top 1 REPORT_NAME FROM X_RPT_REPORTINGLIST),
(SELECT top 1 STANDARD_REPORT FROM X_RPT_REPORTINGLIST),
(SELECT top 1 REPOPT_PACK_VERSION FROM X_RPT_REPORTINGLIST),
(SELECT top 1 [PATH] FROM ReportServer$PORTAL.dbo.Catalog))
Note: changed the column name from PATH(which is a keyword ) to [PATH]
Try like this
INSERT INTO [dbo].[X_RPT_PORTAL_REPORTLIST]
([PORTAL_GROUP_ID], [REPORT_DISPLAY_NAME], [STANDARD_REPORT], [REPORT_PACK_VERSION], [REPORT_PATH])
SELECT rl.ID, rl.REPORT_NAME, rl.STANDARD_REPORT, rl.REPOPT_PACK_VERSION, c.PATH
FROM X_RPT_REPORTINGLIST rl
INNER JOIN ReportServer$PORTAL.dbo.Catalog c ON c.Name = rl.REPORT_NAME
I'm attempting to do an essentially very simple task, which is resulting in:
ORA-00928: missing SELECT keyword
All I'm trying to do is persist the results from periods into table globalTable. Selecting works fine (I'm returned rows) however as soon as I replace it with the Insert I get the above error.
create global temporary table globalTable
(
ids number(11)
);
with periods as
(
select cl.id uniqueId
from inv_mpan_hh_con_lines cl
left join invoice_vat_lines vl on
cl.invoice_id = VL.INVOICE_ID
where rownum < 4
)
--//Issue occurs at insert keyword. If I comment it and uncomment select it works as expected//--
--select uniqueId
insert into globalTable
from periods;
Any pointers are much appreciated.
Try this:
insert into globalTable
with periods as
(
select cl.id uniqueId
from inv_mpan_hh_con_lines cl
left join invoice_vat_lines vl
on cl.invoice_id = VL.INVOICE_ID
where rownum < 4
)
select uniqueId
from periods;
CTE (WITH-clause) is a part of SELECT statement, according to the INSERT syntax you can either specify values or SELECT statement
Could someone help me understand something? When I can, I usually avoid (*) in an SQL statement. Well, today was payback. Here is a scenario:
CREATE TABLE Tbl (Id INT IDENTITY(1, 1) PRIMARY KEY, Name NVARCHAR(16))
INSERT INTO Tbl VALUES (N'John')
INSERT INTO Tbl VALUES (N'Brett')
INSERT INTO Tbl VALUES (NULL)
I could count the number of records where Name is NULL as follows:
SELECT COUNT(*) FROM Tbl WHERE Name IS NULL
While avoiding the (*), I discovered that the following two statements give me two different results:
SELECT COUNT(Id) FROM Tbl WHERE Name IS NULL
SELECT COUNT(Name) FROM Tbl WHERE Name IS NULL
The first statement correctly return 1 while the second statement yields 0. Why or How?
That's because
The COUNT(column_name) function returns the number of values (NULL
values will not be counted) of the specified column
so when you count Id you get expected result, while counting Name no, but the answer provided by query is correct
Everything is described in COUNT (Transact-SQL).
COUNT ( { [ [ ALL | DISTINCT ] expression ] | * } )
ALL - is default
COUNT(*) returns the number of items in a group. This includes NULL values and duplicates.
COUNT(ALL expression) evaluates expression for each row in a group and returns the number of nonnull values.
"COUNT()" does not count NULL values. So basically:
SELECT COUNT(Id) FROM Tbl WHERE Name IS NULL
will return the number of lines where ("ID" IS NOT NULL) AND ("Name" IS NULL); result is "1"
While:
SELECT COUNT(Name) FROM Tbl WHERE Name IS NULL
will count the lines where ("Name" IS NOT NULL) AND ("Name" IS NULL); result will always be 0
As it was said, COUNT (column_name) doesn't count NULL values.
If you don't want use COUNT(*) then use COUNT(1), but actualy you will not see difference in performance.
"Always avoid using *" is one of those blanket statements that people blindly follow. If you knew the reasons why you were avoiding * then you would know that none of those reasons apply when doing count(*).
The * in COUNT(*) is not the same * in SELECT * FROM...
SELECT COUNT(*) FROM T; very specifically means the cardinality of the table expression T.
SELECT COUNT(1) FROM T; will generate the same results as COUNT(*) but if the contents of the parentheses is not * then it must be parsed.
SELECT COUNT(c) FROM T; where c is a nullable column in table T will count the non-null values.
P.S. I'm comfortable with using SELECT * FROM... in the right circumstances.
P.P.S. Your 'table' has no key: consider INSERT INTO Tbl VALUES ('John', 'John', 'John', NULL, NULL, NULL); would be allowed by the results would be nonsense.