subquery must return only one column - php

This query runs successfully in pgAdmin, but when I transfer it in zend I get:
ERROR: subquery must return only one column...
Can someone distinguish the problem?
SELECT "trail_history"."new_audit_trail".*,
(SELECT "admin".list_category_values_new."values"
FROM "admin".list_category_values_new
WHERE CAST(seq AS character varying) = "trail_history"."new_audit_trail"."current_value"
AND "name" = "trail_history"."new_audit_trail"."name") as "values"
FROM "trail_history"."new_audit_trail"
WHERE (capno LIKE '12101062411001%')
AND (recon = '0')
ORDER BY "date_happened" DESC

Your sub-select SELECT "admin".list_category_values_new."values"... has nothing that prevents it from returning multiple rows. You need to use TOP 1 or MAX or something to ensure that only one record comes out of the sub-select.
You can correlate the sub-query so that each record in your main select gets a different single value, but if you're going to use a sub-select it can only return one row per row of output in your main select.

Related

mySQL first select results used as a LIKE for second select

have two tables what i would like to do is run a select against one and the results it returns use that for a second select query on a different table
My first select is
SELECT classes FROM hodnames where initials ='".$_SESSION['username']."' order by id DESC
Which returns two results back, which i would like to use on a second select query, to complicate things further to get the second set results the first set must be used with a LIKE as for example the first set may return "En" and "Ma" the second set of results contains those eg "10MA/1" "10EN/1"
SELECT classes FROM classlist where classes LIKE='results_from_first_query' order by id DESC
I have a select box that is populated by a select query but would like to restrict it to results the user is allowed to have access to.
As you can see it will return more then 1 row.
Thanks for your help

MYSQL count rows instead of showing results

So I have the following query, which I use it to get some analytics stats.
SELECT count(*) as total,CONCAT(YEAR(created),'-',MONTH(created),'-',DAY(created))
as date_only FROM logs where action = 'banner view'
and created BETWEEN '2015-07-03 21:03'
AND '2017-08-02 21:03' group by date_only order by created asc
This works, and it gives me this:
So what I actually need is, the total count of the rows in this case is 20, this is a dummy example, but I need to use this count to check before showing the stats if the data is too big to be displayed on a graphic.
Can this be achieved?
//LE
So the process will be like this:
1. Get a count of the total rows, if the count of rows is smaller than X(number will be in config and it will be a basic if statement), then go ahread and run the above query.
More info:
I actually use this query to display the stats, I just need to adapt it in order to show the total count rows
So the result of thquery should be
total | 20 in this case
I think you would want to use a derived table. Just wrap your original query in parenthesis after the FROM and then give the derived table an alias (in this case tmp). Like so:
SELECT count(*) FROM (
SELECT count(*) as total,CONCAT(YEAR(created),'-',MONTH(created),'-',DAY(created))
as date_only FROM logs where action = 'banner view'
and created BETWEEN '2015-07-03 21:03'
AND '2017-08-02 21:03' group by date_only order by created asc
) as tmp;
If I understand what you want to do correctly, this should work. It should return the actual number of results from your original query.
What's happening is that the results of the parenthesized query are getting used as a sort of virtual table to query against. The parenthesized query returns 20 rows, so the "virtual" table has 20 rows. The outer count(*) just counts how many rows there are in that virtual table.
Based on the PHP tag, I assume you are using PHP to send the queries to MySQL. If so, you can use mysqli_num_rows to get the answer.
If your query result is in $result then:
$total = mysqli_num_rows($result);
Slightly different syntax for Object Oriented style instead of procedural style.
The best part is you don't need an extra query. You perform the original query and get mysqli_num_rows as an extra without running another query. So you can figure out pagination or font size or whatever and then display without doing the query again.
This is an small query but works fine, and give me the total number of rows, you just need add your conditions.
SELECT COUNT(*) FROM table WHERE field LIKE '%condition%'
The group by I think you need to eliminated, becouse, this instead of count the records, divide in all your group by, example: records = 4, with group by you have
1
1
1
1
I hope this help you
You can try this way .
SELECT COUNT(*) FROM ( SELECT count(*) as total,CONCAT(YEAR(created),'-',MONTH(created),'-',DAY(created))
as date_only FROM logs where action = 'banner view'
and created BETWEEN '2015-07-03 21:03'
AND '2017-08-02 21:03' group by date_only HAVING total >=20 ) temp

Check if row exists, The most efficient way?

SQL Queries /P1/
SELECT EXISTS(SELECT /p2/ FROM table WHERE id = 1)
SELECT /p2/ FROM table WHERE id = 1 LIMIT 1
SQL SELECT /P2/
COUNT(id)
id
PHP PDO Function /P3/
fetchColumn()
rowCount()
From the following 3 Parts, What is the best method to check if a row exists or not with and without the ability to retrieve data like.
Retrievable:
/Query/ SELECT id FROM table WHERE id = 1 LIMIT 1
/Function/ rowCount()
Irretrievable
/Query/ SELECT EXISTS(SELECT COUNT(id) FROM table WHERE id = 1)
/Function/ fetchColumn()
In your opinion, What is the best way to do that?
By best I guess you mean consuming the least resources on both MySQL server and client.
That is this:
SELECT COUNT(*) count FROM table WHERE id=1
You get a one-row, one-column result set. If that column is zero, the row was not found. If the column is one, a row was found. If the column is greater that one, multiple rows were found.
This is a good solution for a few reasons.
COUNT(*) is decently efficient, especially if id is indexed.
It has a simple code path in your client software, because it always returns just one row. You don't have to sweat edge cases like no rows or multiple rows.
The SQL is as clear as it can be about what you're trying to do. That's helpful to the next person to work on your code.
Adding LIMIT 1 will do nothing if added to this query. It is already a one-row result set, inherently. You can add it, but then you'll make the next person looking at your code wonder what you were trying to do, and wonder whether you made some kind of mistake.
COUNT(*) counts all rows that match the WHERE statement. COUNT(id) is slightly slower because it counts all rows unless their id values are null. It has to make that check. For that reason, people usually use COUNT(*) unless there's some chance they want to ignore null values. If you put COUNT(id) in your code, the next person to work on it will have to spend some time figuring out whether you meant anything special by counting id rather than *.
You can use either; they give the same result.

INSERT INTO table SELECT not giving correct last_id

I have 2 tables with similar columns in MYSQL. I am copying data from one to another with INSERT INTO table2 SELECT * FROM table1 WHERE column1=smth. I have different columns as autoincrement and KEY in tables. When I use mysqli_insert_id i get the first one rather then last one inserted. Is there any way to get the last one?
Thanks
There is no inherit ordering of data in a relational database. You have to specify which field it is that you wish to order by like:
INSERT INTO table2
SELECT *
FROM table1
WHERE column1=smth
ORDER BY <field to sort by here>
LIMIT 1;
Relying on the order a record is written to a table is a very bad idea. If you have an auto-numbered id on table1 then just use ORDER BY id DESC LIMIT 1 to sort the result set by ID in descending order and pick the last one.
Updated to address OP's question about mysqli_insert_id
According to the Mysql reference the function called here is last_insert_id() where it states:
Important If you insert multiple rows using a single INSERT statement,
LAST_INSERT_ID() returns the value generated for the first inserted
row only. The reason for this is to make it possible to reproduce
easily the same INSERT statement against some other server.
Unfortunately, you'll have to do a second query to get the true "Last inserted id". Your best bet might be to run a SELECT COUNT(*) FROM table1 WHERE column1=smth; and then use that count(*) return to add to the mysqli_insert_id value. That's not great, but if you have high volume where this one function is getting hit a lot, this is probably the safest route.
The less safe route would be SELECT max(id) FROM table2 or SELECT max(id) FROM table2 Where column1=smth. But... again, depending on your keys and the number of times this insert is getting hit, this might be risky.

MySQL Benchmark

I am trying to use MySQL benchmark to test some queries. But, I am running to an error.
SELECT benchmark (10000, (select title from user));
and in return I get this error;
ERROR 1242 (21000): Subquery returns more than 1 row
Does anyone know how to benchmark a query?
Thanks
select title from user
This returns multiple rows, which won't work.
Refer to this link:
http://dev.mysql.com/doc/refman/5.0/en/information-functions.html#function_benchmark
The expression you pass must return a scalar result.
You need to change the query such that it returns a single row:
ex:
select title from user where user_name = 'some_user'
you can use the mysqlslap utility to benchmark queries, see:
http://dev.mysql.com/doc/refman/5.1/en/mysqlslap.html
From http://dev.mysql.com/doc/refman/5.0/en/information-functions.html#function_benchmark
Only scalar expressions can be used.
Although the expression can be a
subquery, it must return a single
column and at most a single row. For
example, BENCHMARK(10, (SELECT * FROM
t)) will fail if the table t has more
than one column or more than one row.
Try
SELECT BENCHMARK(10000, (SELECT title FROM user LIMIT 1));

Categories