Am trying to select the day and month part for a range of date of a date field in mysql and its given me this error"Operand should contain 1 column(s)".
tablename is personal
date field name is dob
"SELECT *
FROM personal
WHERE (EXTRACT(MONTH
FROM dob),
EXTRACT(DAY
FROM dob)) BETWEEN '$fromdate' AND '$todate'"
dob is date field and the $fromdate and $todate holds a date input from the screen like "2014-04-30" and "2014-06-30
Using WHERE clause you can compare multiple values but one each at a time.
In your statement WHERE is trying to use both MONTH and DAY as separate values comma separated but comparing with $fromdate and $tdate, which is not correct.
And hence is the error:
Operand should contain 1 column(s)
You may be looking for a solution like this:
If $fromdate and $todate are in the format of mmdd, then
SELECT * FROM personal
WHERE date_format( dob, '%m%d' )
BETWEEN '$fromdate' AND '$todate'
You need to use CONCAT in order to merge day and month from your dob column and then compare using between clause
SELECT
*
FROM
personal
WHERE
CONCAT(EXTRACT(MONTH FROM dob),'-',EXTRACT(DAY FROM dob))
BETWEEN '$fromdate' AND '$todate'
Or better to use DATE_FORMAT to get the month and day only but make sure you have standard date object stored in column, and the format you provide in DATE_FROMAT must match with the format of your provided parameters
SELECT
*
FROM
personal
WHERE
DATE_FROMAT(dob,'%m-%d')
BETWEEN '$fromdate' AND '$todate'
Just in case anyone else runs across this error (I fought with it for hours before realizing my mistake)
You will also get this error if you accidentally put the cols for a SELECT in parenthesis
So if you are in a hurry and cut and paste your field list and type...
INSERT INTO mytablename(col1, col2, col3)
SELECT (col1, col2, col3) FROM anothertable WHERE col4 = 1;
instead of
INSERT INTO mytablename(col1, col2, col3)
SELECT col1, col2, col3 FROM anothertable WHERE col4 = 1;
it throws the Operand should contain 1 column(s) error.
Related
I'm updating an old website and one of the queries isn't working anymore:
SELECT * FROM tbl WHERE col1 IS NULL GROUP BY col2 ORDER BY col2
I noticed if I dropped the GROUP BY it works, but the result set doesn't match the original:
SELECT * FROM tbl WHERE col1 IS NULL ORDER BY col2
So I tried reading up on GROUP BY in the docs to see what might be the issue, and it seemed to suggest not using * to select all the fields, but explicitly using the column name so I tried it with just the column that was being ordered and grouped:
SELECT col2 FROM tbl WHERE col1 IS NULL GROUP BY col2 ORDER BY col2
Which works but after looking through the code the query requires 2 columns in the query so whoever added * was overdoing it, but if I add that column produces an error, similarly adding a third column produces the same error:
SELECT col2, col3 FROM tbl WHERE col1 IS NULL GROUP BY col2 ORDER BY col2
SELECT col1, col2, col3 FROM tbl WHERE col1 IS NULL GROUP BY col2 ORDER BY col2
Can anyone tell me why this last query doesn't work? I can't decipher why from the docs, but this is the minimum query required to get the result set I need.
Running the query in Adminer I get this error
Error in query (1055): Expression #2 of SELECT list is not in GROUP BY
clause and contains nonaggregated column 'name.table.column'
which is not functionally dependent on columns in GROUP BY clause; this is
incompatible with sql_mode=only_full_group_by
You need to be careful when you use GROUP BY. Once you understand what GROUP BY does, you will know the issue yourself. It does an aggregation on your data or in other words, it reduces your data by doing some operation on the raw entries and creating new reduced number of entries on which some aggregation function has been applied(SUM, COUNT, AVG, etc.)
The fields you provide in the GROUP BY clause represents the level of aggregation/roll-up you are going for.
SELECT col2, col3 FROM tbl WHERE col1 IS NULL GROUP BY col1 ORDER BY col1
Here you are trying to do the aggregation at col1 level, meaning that for every distinct value present in column col1, there will be some operation done on some other columns you provide in SELECT clause(here col2,col3) so that in the output you have non-repeating values in col1 and some rolled-up values of col2 and col3 against each distinct col1 value based on what function you apply(SUM, COUNT, AVG, etc.).
How do you apply this function? That is what is missing in your above query. To solve it, you need to apply some aggregation function on the fields that are present in the SELECT clause but not in GROUP BY clause. Taking an example of SUM, try this:
SELECT SUM(col2), SUM(col3) FROM tbl WHERE col1 IS NULL GROUP BY col1 ORDER BY col1
OR for a better idea, removing WHERE filter and checking the output by running:
SELECT col1, SUM(col2), SUM(col3) FROM tbl GROUP BY col1 ORDER BY col1
Additionally, the reason why your other query
SELECT col2 FROM tbl WHERE col1 IS NULL GROUP BY col2 ORDER BY col2
worked is because you need not apply aggregation to the field(here col2) which is present in the GROUP BY clause.
First of all, when query() returns false, you should find out what the error was. You seem to be using PDO, so I will direct you to this page: http://php.net/manual/en/pdo.error-handling.php
TL;DR - you should enable PDO exceptions, or else you need to write code to check the result of every call to query(), prepare(), and execute() to see if an error occurred. And if so, use errorInfo() to find out the actual error. Doing anything else is flying blind!
Error in query (1055): Expression #2 of SELECT list is not in GROUP BY
clause and contains nonaggregated column 'webvictoria.cats_oct.matchLink'
which is not functionally dependent on columns in GROUP BY clause; this is
incompatible with sql_mode=only_full_group_by
This is a common issue. See dozens of questions tagged mysql-error-1055.
I guess you just upgraded to MySQL 5.7. MySQL 5.7 enabled strict mode by default, so I guess you just upgraded. Prior to MySQL 5.6, strict mode was optional and not enabled by default.
See: https://dev.mysql.com/doc/refman/5.7/en/group-by-handling.html
You can't write ambiguous queries. If you GROUP BY col2, which value in the group of rows of each group should be used for col1 and col3? It's ambiguous.
Without strict mode, MySQL chooses an arbitrary row from the group. With strict mode, it reverts to standard SQL behavior, and disallows the ambiguous query. This is how most other brands of SQL database behave, by the way.
To fix it, you must follow this rule: Every column in your select list must be one of:
A column in your GROUP BY clause
A column functionally dependent on the columns in your GROUP BY clause (so there can only be one value)
Used in an aggregate function like MIN(), MAX(), COUNT(), SUM(), AVG(), or GROUP_CONCAT()
Some people choose to disable strict mode in MySQL 5.7 for the sake of "getting the code working again." But it isn't working—it's just giving ambiguous results like it did before MySQL 5.7.
It's better to fix the logic of your queries.
This query:
SELECT *
FROM tbl
WHERE col1 IS NULL
GROUP BY col1
ORDER BY col1;
never really worked. It may have seemed to work, but you were just lucky. You have unaggregated columns in the SELECT. These come from an arbitrary row.
You can do something like this to get values from other columns:
SELECT col1, min(col2), min(col3)
FROM tbl t
WHERE col1 IS NULL AND
GROUP BY col1
ORDER BY col1;
The reason it didn't work is because you need to use one of the selection criteria in the GROUP BY and the ORDER BY. So if you wanted to group by col1, you would need to do this:
SELECT col1, col2, col3
FROM tbl
WHERE
col1 IS NULL
GROUP BY col1
ORDER BY col1
;
Without selecting that field, you are basically saying "Hey go get me every phone number in California" Then after you get that you say "Now order them by first name and group them by last name" and DBMS says "but... I don't have any of that"
try this
SELECT col2, col3 FROM tbl WHERE col1 IS NULL GROUP BY col2, col3 ORDER BY col2, col3
I'm trying to copy data from one table to another.
For that matter I'm using this:
INSERT INTO radacct_2011_2012 SELECT 'RadAcctId, AcctSessionId, AcctUniqueId, UserName, Realm, NASIPAddress, NASPortId, NASPortType, AcctStartTime, AcctStopTime, AcctSessionTime, AcctAuthentic, ConnectInfo_start, ConnectInfo_stop, AcctInputOctets, AcctOutputOctets, CalledStationId, CallingStationId, AcctTerminateCause, ServiceType, FramedProtocol, FramedIPAddress, AcctStartDelay, AcctStopDelay' from radacct where 'AcctStartTime' >= '2011' AND 'AcctStartTime' <= '2012';
When I try to run it I get the following error:
ERROR 1136 (21S01): Column count doesn't match value count at row 1
I'm reading about it and none of the solutions that I found helped me.
You only SELECT one value because you escape the whole column list with '. So MySQL interpret this as a string value, not a column list.
So you should use the following query instead:
INSERT INTO `radacct_2011_2012`
SELECT `RadAcctId`, `AcctSessionId`, `AcctUniqueId`, `UserName`, `Realm`, `NASIPAddress`, `NASPortId`, `NASPortType`, `AcctStartTime`, `AcctStopTime`, `AcctSessionTime`, `AcctAuthentic`, `ConnectInfo_start`, `ConnectInfo_stop`, `AcctInputOctets`, `AcctOutputOctets`, `CalledStationId`, `CallingStationId`, `AcctTerminateCause`, `ServiceType`, `FramedProtocol`, `FramedIPAddress`, `AcctStartDelay`, `AcctStopDelay`
FROM `radacct`
WHERE `AcctStartTime` >= '2011' AND `AcctStartTime` <= '2012';
There is a general problem on your query using the ' in the wrong situations. You are using ' on column names of the WHERE part too. MySQL compares 'AcctStartTime' >= '2011' as false because the string values (in this example AcctStartTime and 2011) are never equal. If you want to escape column names you have to use the backtick (``).
You should read When to use single quotes, double quotes, and backticks in MySQL to get the difference between the different escape possibilities.
Tim provided a demo to confirm that double quotes (and single quotes too) can not be used to escape column names.
Please check the no of columns in the first table and check the no of columns in the second table.
You should also match the order of the columns. i.e.
Table 1
col1 col2 col3 col4
Table 2
col1 col2 col3 col4
insert into table1 select col1,col2,col3,col4 from table2 where col1 = '2';
It will give error if the order is not match or the no of column is greater or less in the first table.
I need to calculate the sum of one column(col2) , but the column has both numbers and text. How do I exclude the text alone before I use sum()?
The table has around 1 million rows, so is there any way other than replacing the text first?
My query will be :
Select col1,sum(col2) from t1 group by col1,col2
Thanks in advance
You can use regexp to filter the column:
Select col1,sum(col2) from t1 WHERE col2 REGEXP '^[0-9]+$' group by col1,col2
You could use MySQL built in REGEXP function.
to learn more visit : https://dev.mysql.com/doc/refman/5.1/en/regexp.html
Or another way is using CAST or CONVERT function
to learn in detail : https://dev.mysql.com/doc/refman/5.0/en/cast-functions.html
Hope this is helpful
Assuming you mean the number is at the beginning of the tex, the easiest way is simply to use implicit conversion:
Select col1, sum(col2 + 0)
from t1
group by col1, col2;
If col2 starts with a non-numeric character, then MySQL will return 0. Otherwise, it will convert the leading numeric characters to a number.
Note that your query doesn't really make sense, because you are aggregating by col2 as well as including it in the group by. I suspect you really want:
Select col1, sum(col2 + 0)
from t1
group by col1;
I've the following query:
INSERT INTO StatisticalConsultationAgreement VALUES (
queryType, entityCode, entityType, queryClass,queryTables,period,
COUNT(queryClass), SUM(numberRecords), SUM(recordsFound),
SUM(NorecordsFound), NOW(), 'system');
SELECT
MONTH(EndDateTimeProcessing),YEAR(EndDateTimeProcessing),
entityType,
entityCode,
queryType,
queryClass,
EndDateTimeProcessing as period
FROM agreementFile
WHERE
MONTH(EndDateTimeProcessing)=MONTH(DATE_SUB( CURDATE(), INTERVAL 1 MONTH ))
AND YEAR(EndDateTimeProcessing)=YEAR(CURDATE())
GROUP BY entityType,entitycode,queryType, queryClass;
When I run the query I get the next mistake:
Error code 1111, SQL state HY000: Invalid use of group function
Line 1, column 1
Executed successfully in 0,002 s.
Line 5, column 2
why ocurre this?
how to fix it?
You are mixing a values statement with a select statement in insert. You only need select. This is my best guess on what you want:
INSERT INTO StatisticalConsultationAgreement
SELECT queryType, entityCode, entityType, queryClass,queryTables,period,
COUNT(queryClass), SUM(numberRecords), SUM(recordsFound),
SUM(NorecordsFound), NOW(), 'system'
FROM agreementFile
WHERE MONTH(EndDateTimeProcessing)=MONTH(DATE_SUB( CURDATE(), INTERVAL 1 MONTH )) AND
YEAR(EndDateTimeProcessing)=YEAR(CURDATE())
GROUP BY entityType, entitycode, queryType, queryClass;
However, you should also list the column names for StatisticalConsultationAgreement in the insert statement.
You are not grouping EndDateTimeProcessing and when you try to do the Insert it can't figure out which EndDateTimeProcessing value, from the grouped rows, it should take.
The solution is either you add it on your group clause:
GROUP BY entityType,entitycode,queryType, queryClass, EndDateTimeProcessing;
Or you use a function group as MAX(), MIN(), etc.
Best Regards
EDIT
As said by Gordon Linoff, you are also mixing the query with the INSERT, everything should be gotten by the query.
The right syntax should be:
INSERT INTO StatisticalConsultationAgreement
SELECT
'queryType', --I don't know what is the query type so i put it on single quote
entityCode,
entityType,
queryClass,
queryTables,
MAX(EndDateTimeProcessing), --Period put on group function MAX, but it cant be grouped below or put into another group function
COUNT(queryClass), --
SUM(numberRecords), -- ASUMING THOSE ARE COLUMNS IN agreementFile
SUM(recordsFound), --
SUM(NorecordsFound),--
NOW(),
'system'
FROM agreementFile
WHERE
MONTH(EndDateTimeProcessing)=MONTH(DATE_SUB( CURDATE(), INTERVAL 1 MONTH ))
AND YEAR(EndDateTimeProcessing)=YEAR(CURDATE())
GROUP BY entityType,entitycode,queryType, queryClass;
The fields MONTH(EndDateTimeProcessing),YEAR(EndDateTimeProcessing), for the query were removed because i didn't know where thouse should be
My question in title, so
If i had:
SELECT * FROM tbl WHERE date BETWEEN "date[0][start]"
AND "date[0][end]" OR date BETWEEN "date[1][start]" AND "date[1][end]"
Can i somehow separate results in appliance with where clause
Each condition evaluates to either FALSE (0) or TRUE (1). It is possible to select the results of the expressions as values and even sort the result by these values:
SELECT
col1, col2, ..., coln,
date BETWEEN "date[0][start]" AND "date[0][end]" AS first,
date BETWEEN "date[1][start]" AND "date[1][end]" AS second
FROM tbl
WHERE date BETWEEN "date[0][start]" AND "date[0][end]"
OR date BETWEEN "date[1][start]" AND "date[1][end]"
ORDER BY first