Unknown column error accessing outer query column inside subquery - mysql

I don't know how to explain my problem better than just showing the code and the error.
The following query is a minimal example for the problem I have encountered
UPDATE stops AS stops1 SET real_stop_id = (
SELECT MIN(served_by2.stop_id)
FROM served_by AS served_by1
INNER JOIN served_by AS served_by2
USING(route_short_name)
WHERE served_by1.stop_id = stops.stop_id
);
It returns the following error.
ERROR 1054 (42S22): Unknown column 'stops.stop_id' in 'where clause'
I'm using the timetable data for my city's tram network in the Google Transit Feed Specification format
https://developers.google.com/transit/gtfs/reference
In addition to this I have created and populated a table served_by.
mysql> describe served_by;
+------------------+---------+------+-----+---------+-------+
| Field | Type | Null | Key | Default | Extra |
+------------------+---------+------+-----+---------+-------+
| stop_id | int(11) | YES | | NULL | |
| route_short_name | text | YES | | NULL | |
+------------------+---------+------+-----+---------+-------+
2 rows in set (0.00 sec)
mysql> select * from served_by limit 5;
+---------+------------------+
| stop_id | route_short_name |
+---------+------------------+
| 378 | 19 |
| 378 | 19 |
| 378 | 19 |
| 378 | 19 |
| 398 | 5 |
+---------+------------------+
5 rows in set (0.06 sec)
For completeness, here is the stops table, which follows the GTFS format except for the column real_stop_id (which has no data), that I am currently trying to populate.
mysql> describe stops;
+--------------+--------------+------+-----+---------+----------------+
| Field | Type | Null | Key | Default | Extra |
+--------------+--------------+------+-----+---------+----------------+
| id | int(11) | NO | PRI | NULL | auto_increment |
| stop_id | int(11) | YES | MUL | NULL | |
| real_stop_id | int(11) | YES | | NULL | |
| stop_no | varchar(30) | YES | MUL | NULL | |
| stop_name | varchar(150) | YES | MUL | NULL | |
| stop_lat | double | YES | | NULL | |
| stop_lon | double | YES | | NULL | |
+--------------+--------------+------+-----+---------+----------------+
7 rows in set (0.00 sec)
mysql> select * from stops limit 5;
+----+---------+--------------+---------+--------------------------------------------+-------------------+------------------+
| id | stop_id | real_stop_id | stop_no | stop_name | stop_lat | stop_lon |
+----+---------+--------------+---------+--------------------------------------------+-------------------+------------------+
| 1 | 10311 | 947 | 45 | 45-Glenferrie Rd/Wattletree Rd (Malvern) | -37.862296736384 | 145.028194441473 |
| 2 | 10371 | 946 | 44 | 44-Duncraig Ave/Wattletree Rd (Armadale) | -37.8618932396197 | 145.025090664641 |
| 3 | 1083 | 1083 | 42 | 42-Clyde St/Raleigh Rd (Maribyrnong) | -37.7696986370071 | 144.898841257316 |
| 4 | 11285 | 940 | 43 | 43-Egerton Rd/Wattletree Rd (Armadale) | -37.8615917660895 | 145.02270030676 |
| 5 | 1185 | 1185 | 50 | 50-Vincent St/Wattletree Rd (Malvern East) | -37.8643850684538 | 145.04371198053 |
+----+---------+--------------+---------+--------------------------------------------+-------------------+------------------+
5 rows in set (0.06 sec)

You have renamed it to stops1. You need to use the alias instead of the original table name:
UPDATE stops s
SET real_stop_id = (SELECT MIN(sb2.stop_id)
FROM served_by sb1 JOIN
served_by sb2
USING (route_short_name)
WHERE sb1.stop_id = s.stop_id
);
I find that table abbreviations are easier to write and read.

Related

mysql insert max min value grouped by date

This is my table schema:
mysql> describe stocks;
+-----------+-------------+------+-----+---------+----------------+
| Field | Type | Null | Key | Default | Extra |
+-----------+-------------+------+-----+---------+----------------+
| id | int(11) | NO | PRI | NULL | auto_increment |
| symbol | varchar(32) | NO | | NULL | |
| date | datetime | NO | | NULL | |
| value | float(10,3) | NO | | NULL | |
| contracts | int(8) | NO | | NULL | |
| open | float(10,3) | NO | | NULL | |
| close | float(10,3) | NO | | NULL | |
| high | float(10,3) | NO | | NULL | |
| low | float(10,3) | NO | | NULL | |
+-----------+-------------+------+-----+---------+----------------+
9 rows in set (0.00 sec)
I added two new columns named high and low so they are empty now.
My goal is fill up these columns with the relative max(value),min(value) based on each daytime!
My first insight is this query:
select distinct DATE(date),max(value) as max,min(value) as min from stocks GROUP BY DATE(date);
...
| 2017-02-20 | 19130.000 | 18875.000 |
| 2017-02-21 | 19170.000 | 18780.000 |
| 2017-02-22 | 19125.000 | 18745.000 |
| 2017-02-23 | 18980.000 | 18765.000 |
| 2017-02-24 | 18840.000 | 18505.000 |
+------------+-----------+-----------+
that achieve the first step, now I should join these results with each rows:
| 900363 | FIB7C | 2017-02-20 17:49:44 | 18930.000 | 1 | 0.000 | 0.000 | 0.000 | 0.000 |
and insert the correct value based on DATE(date) but I still not catch to do with INSERT INTO.
Thanks for helps regards.
You can do this with a join in the update along with an aggregation to calculate the values:
update stocks s join
(select date(date) as d, max(value) as dhigh, min(value) as dlow
from stocks s
group by date(date)
) sd
on date(s.date) = sd.d
set s.high = sd.dhigh,
s.low = sd.dlow;

Insert value in a table

I have a question about inserting row in an table which is already created.
This is my table :
mysql> describe llx_document_model ;
+-------------+--------------+------+-----+---------+----------------+
| Field | Type | Null | Key | Default | Extra |
+-------------+--------------+------+-----+---------+----------------+
| rowid | int(11) | NO | PRI | NULL | auto_increment |
| nom | varchar(50) | YES | MUL | NULL | |
| entity | int(11) | NO | | 1 | |
| type | varchar(20) | NO | | NULL | |
| libelle | varchar(255) | YES | | NULL | |
| description | text | YES | | NULL | |
+-------------+--------------+------+-----+---------+----------------+
6 rows in set (0.00 sec)
If I print the table :
mysql> select * from llx_document_model ;
+-------+----------+--------+-------------------+---------+-------------+
| rowid | nom | entity | type | libelle | description |
+-------+----------+--------+-------------------+---------+-------------+
| 1 | standard | 1 | deplacement | NULL | NULL |
| 7 | soleil | 1 | ficheinter | NULL | NULL |
| 13 | rouget | 1 | shipping | NULL | NULL |
| 14 | typhon | 1 | delivery | NULL | NULL |
| 16 | aurore | 1 | supplier_proposal | NULL | NULL |
| 17 | muscadet | 1 | order_supplier | NULL | NULL |
| 18 | baleine | 1 | project | NULL | NULL |
| 19 | einstein | 1 | order | NULL | NULL |
| 21 | azur | 1 | propal | NULL | NULL |
| 23 | strato | 1 | contract | strato | NULL |
| 32 | crabe | 1 | invoice | crabe | NULL |
+-------+----------+--------+-------------------+---------+-------------+
11 rows in set (0.00 sec)
I want to add a row, so I write :
mysql> INSERT INTO llx_document_model
-> VALUES(NULL, moriba, 1, invoice, moriba, NULL);
But I get this error :
ERROR 1054 (42S22): Unknown column 'moriba' in 'field list'
Do you have some idea about my problem ? I don't see really where I made an error.
Thank you by advance !
string should be enclosed by (')single quotes
mysql> INSERT INTO llx_document_model VALUES(NULL, 'moriba', 1, 'invoice', 'moriba', NULL);

Why is SELECT COUNT() returning an aggregated number when I'm expecting a count of each row?

So I'm struggling with this very (very) basic MySQL query which is supposed to retrieve courrier records ordered by number of joined reactions.
I have this table:
mysql> describe courrier;
+--------------+--------------+------+-----+---------+----------------+
| Field | Type | Null | Key | Default | Extra |
+--------------+--------------+------+-----+---------+----------------+
| id | int(11) | NO | PRI | NULL | auto_increment |
| name | varchar(255) | NO | | NULL | |
| envoi | datetime | NO | | NULL | |
| intro | longtext | NO | | NULL | |
| courrier | longtext | NO | | NULL | |
| slug | varchar(255) | NO | | NULL | |
| categorie_id | int(11) | YES | MUL | NULL | |
| reponse | longtext | YES | | NULL | |
| recu | datetime | YES | | NULL | |
| published | tinyint(1) | NO | | NULL | |
| image_id | int(11) | YES | UNI | NULL | |
| like_count | int(11) | YES | | NULL | |
+--------------+--------------+------+-----+---------+----------------+
12 rows in set (0.02 sec)
Which has:
mysql> select count(id) from courrier;
+-----------+
| count(id) |
+-----------+
| 56 |
+-----------+
1 row in set (0.00 sec)
Joined with:
mysql> describe reaction;
+-------------+--------------+------+-----+---------+----------------+
| Field | Type | Null | Key | Default | Extra |
+-------------+--------------+------+-----+---------+----------------+
| id | int(11) | NO | PRI | NULL | auto_increment |
| courrier_id | int(11) | YES | MUL | NULL | |
| date | datetime | NO | | NULL | |
| ip | varchar(15) | NO | | NULL | |
| reaction | longtext | NO | | NULL | |
| url | varchar(255) | YES | | NULL | |
| name | varchar(255) | NO | | NULL | |
| status | int(11) | NO | | NULL | |
| email | varchar(255) | YES | | NULL | |
+-------------+--------------+------+-----+---------+----------------+
9 rows in set (0.01 sec)
Which has:
mysql> select count(id) from reaction;
+-----------+
| count(id) |
+-----------+
| 236 |
+-----------+
1 row in set (0.00 sec)
On: ALTER TABLE reaction ADD CONSTRAINT FK_5DA165A18BF41DC7 FOREIGN KEY (courrier_id) REFERENCES courrier (id);
(backticks removed for readability)
So when I run this query:
SELECT c0_.id AS id_0,
c0_.name AS name_1,
c0_.slug AS slug_2,
c0_.envoi AS envoi_3,
c0_.intro AS intro_4,
c0_.courrier AS courrier_5,
c0_.reponse AS reponse_6,
c0_.published AS published_7,
c0_.like_count AS like_count_8,
c0_.recu AS recu_9,
COUNT(r1_.id) AS sclr_10,
c0_.image_id AS image_id_11,
c0_.categorie_id AS categorie_id_12
FROM courrier c0_
INNER JOIN reaction r1_ ON c0_.id = r1_.courrier_id
ORDER BY sclr_10 DESC LIMIT 25
I'm quite naturally expecting to be provided with one row per record in courrier along with a additional column specifying the number of joined reaction records.
But I'm returned: 1 row in set (0.03 sec). It's the first record inserted in courrier and the additional column is filled with the number 242.
What did I do wrong?
You should use a group by clause, otherwise the count will aggregate the whole result set:
SELECT c0_.id AS id_0 /*, ...*/,
COUNT(r1_.id) AS sclr_10
FROM courrier c0_
INNER JOIN reaction r1_ ON c0_.id = r1_.courrier_id
GROUP BY c0_.id
ORDER BY sclr_10 DESC
LIMIT 25
Note: if you are also interested in courrier records that have no corresponding record in reaction (count = 0), then use LEFT JOIN instead of INNER JOIN.

insert values of query into table, even if no result in query (insert 0 values)

I am trying to solve a probably simple thing, being no expert at all # mysql
I have this first table 'online_players'
mysql> show columns from online_players;
+-------------------+--------------+------+-----+---------+-------+
| Field | Type | Null | Key | Default | Extra |
+-------------------+--------------+------+-----+---------+-------+
| Agent | varchar(255) | YES | | NULL | |
| Name | varchar(255) | YES | | NULL | |
| Alias | varchar(255) | YES | | NULL | |
| Begin_Date | varchar(100) | YES | | NULL | |
| LastBalanceUpdate | varchar(100) | YES | | NULL | |
| Session_minutes | varchar(100) | YES | | NULL | |
| Balance | varchar(100) | YES | | NULL | |
| Product | varchar(100) | YES | | NULL | |
+-------------------+--------------+------+-----+---------+-------+
8 rows in set (0.04 sec)
which is droped, recreated and value inserted every 3 minutes, it shows players on a website currently playing...
I then have this table 'players_count' :
mysql> show columns from players_count;
+---------------+--------------+------+-----+---------+----------------+
| Field | Type | Null | Key | Default | Extra |
+---------------+--------------+------+-----+---------+----------------+
| date_count | varchar(50) | YES | | NULL | |
| players_count | varchar(10) | YES | | NULL | |
| product | varchar(10) | YES | | NULL | |
| avg_balance | varchar(100) | YES | | NULL | |
| id | int(11) | NO | PRI | NULL | auto_increment |
+---------------+--------------+------+-----+---------+----------------+
5 rows in set (0.07 sec)
When the table online_players is updated, the table players_count is updated with a specific insert:
USE livefeed;
INSERT INTO players_count(
date_count,players_count,product, avg_balance)
SELECT
now(),
count(Name) as Players,
Product,
Avg(Balance)
FROM
online_players
GROUP BY Product;
It works ok when at list 1 player is online:
mysql> select * from players_count
-> ;
+---------------------+---------------+---------+-------------+----+
| date_count | players_count | product | avg_balance | id |
+---------------------+---------------+---------+-------------+----+
| 2016-03-28 17:09:02 | 2 | USD | 0.06 | 1 |
| 2016-03-28 17:12:01 | 1 | USD | 0.12 | 2 |
| 2016-03-28 17:15:00 | 1 | USD | 0.12 | 3 |
| 2016-03-28 17:18:00 | 1 | USD | 0.12 | 4 |
| 2016-03-28 17:21:01 | 1 | USD | 0.12 | 5 |
| 2016-03-28 17:24:00 | 1 | USD | 0.12 | 6 |
+---------------------+---------------+---------+-------------+----+
6 rows in set (0.21 sec)
But I would also like to record a row in table players_count when NO player is online even if my query above = 0, for example:
+---------------------+---------------+---------+-------------+----+
| date_count | players_count | product | avg_balance | id |
+---------------------+---------------+---------+-------------+----+
| 2016-03-28 18:01:00 | 0 | USD | 0 | 7 |
| 2016-03-28 18:01:00 | 0 | FUN | 0 | 8 |
I use the table players_count to generate "real time" graphs and need to have 0 values for every specific date.
It might be simple but I have not found any solution online...
How shoud I modify my Insert/query to do this?
Thanks for your help

order by inside group_contact mysql

I have a below mysql query. It's returns wrong value. Please HELP ME to resolve this issue.
SELECT
T1.PARENT_ID,
GROUP_CONCAT(
IF(T2.PROPERTIES IS NULL, "NA", T2.PROPERTIES)
ORDER BY T1.ORDER_INDEX ASC
) AS DATA
FROM TABLE_1 T1
JOIN TABLE_2 T2
ON T1.ID=T2.ID
WHERE T1.AUTHOR="123"
GROUP BY T1.PARENT_ID
ORDER BY T1.PARENT_ID;
Mysql Version ===> 5.0.27-standard-log
The above query returns:
+-----------+---------------+
| parent_id | data |
+-----------+---------------+
| 12345 | te,test1,test |
| 23456 | NA |
+-----------+---------------+
2 rows in set (0.00 sec)
_
But, it should be:
+-----------+---------------+
| parent_id | data |
+-----------+---------------+
| 12345 | NA,test1,test |
| 23456 | NA |
+-----------+---------------+
2 rows in set (0.00 sec)
-
-
########################### TABLE DATA ############################
mysql> select * from Table_1;
+----+-----------+--------+-------------+
| id | parent_id | author | order_index |
+----+-----------+--------+-------------+
| 1 | 12345 | 123 | 3 |
| 2 | 12345 | 123 | 1 |
| 3 | 23456 | 123 | 1 |
| 4 | 12345 | 123 | 2 |
+----+-----------+--------+-------------+
4 rows in set (0.00 sec)
mysql> select * from Table_2;
+----+------------+
| id | properties |
+----+------------+
| 1 | test |
| 2 | NULL |
| 3 | NULL |
| 4 | test1 |
+----+------------+
4 rows in set (0.00 sec)
-
-
########################### TABLE MODEL ############################
mysql> desc Table_1;
+-------------+-----------+------+-----+---------+-------+
| Field | Type | Null | Key | Default | Extra |
+-------------+-----------+------+-----+---------+-------+
| id | int(11) | NO | PRI | | |
| parent_id | char(100) | YES | | NULL | |
| author | char(100) | YES | | NULL | |
| order_index | int(11) | YES | | 0 | |
+-------------+-----------+------+-----+---------+-------+
4 rows in set (0.00 sec)
mysql> desc Table_2;
+------------+---------+------+-----+---------+-------+
| Field | Type | Null | Key | Default | Extra |
+------------+---------+------+-----+---------+-------+
| id | int(11) | NO | PRI | | |
| properties | text | YES | | NULL | |
+------------+---------+------+-----+---------+-------+
2 rows in set (0.00 sec)