Access a parent field from sub query in mysql - mysql

I'm trying to access a field being called from the parent query within a nested one and here is my table
TABLE: reminders.
Columns: id:PK, rid:VARCHAR, title:VARCHAR, remind:Integer, start_day:DATE
SELECT id, remind, rid, title
FROM reminders
WHERE DATEDIFF(start_day, NOW()) <= (SELECT LEAST(3, remind))
Basically the second "remind" column in the LEAST() command is suppossed to reference the first "remind" column value for every row being spanned but for reasons that I can't just imagine i keep getting unexpected returns.
EDIT
In response to Sir Gordons that i provide more detailed info, I will try my best but I really do not know how to present table data here, but i'll try.
So basically i'm trying to SELECT all items from the reminders table WHERE the DIFFERENCE between the SET DAY (start_day) and TODAY doesn't exceed one of TWO values, those are either 3 or the value set in the remind column of the current row. Basically if the value set there is less than 3 then it should be used instead, but if it exceeds 3, 3 should be chosen. Here's a visual of the table.
+---+-----------------+--------------------+-----------------+-------------+
|id | rid | title | start_day | remind |
+---|-----------------|--------------------|-----------------|-------------|
|1 | ER456GH | This is real deep | 2014-01-01 | 10 |
|2 | OUBYV90 | This is also deep | 2014-01-13 | 10 |
|3 | UI90POL | This is deeper | 2014-01-13 | 60 |
|4 | TWEET90 | This is just deep | 2014-01-14 | 0 |
+---+-----------------+--------------------+-----------------+-------------+
So in editing this I realized that there was a false table entry under remind on the 4th entry that was causing it to pull false (i.e where remind = 0). Sigh. Some serious short sight on my part/lack of sleep I guess. The query does work . Thanks again.

You don't need a subquery here. Does this work?
SELECT id, remind, rid, title
FROM reminders
WHERE DATEDIFF(start_day, NOW()) <= LEAST(3, remind);

Related

Mysql insertion order [duplicate]

This question already has answers here:
Return rows in the exact order they were inserted
(4 answers)
Closed 4 years ago.
I don't know whether it is already answered. I hadn't got any answers.In Mysql tables, the rows will be arranged in the order of primary key. For example
+----+--------+
| id | name |
+----+--------+
| 1 | john |
| 2 | Bryan |
| 3 | Princy |
| 5 | Danny |
+----+--------+
If I insert anothe row insert into demo_table values(4,"Michael").The table will be like
+----+---------+
| id | name |
+----+---------+
| 1 | john |
| 2 | Bryan |
| 3 | Princy |
| 4 | Michael |
| 5 | Danny |
+----+---------+
But I need the table to be like
+----+---------+
| id | name |
+----+---------+
| 1 | john |
| 2 | Bryan |
| 3 | Prince |
| 5 | Danny |
| 4 | Michael |
+----+---------+
I want the row to be concatenated to the table i.e.,
The rows of the table should be in the order of insertion.Can anybody suggest me the query to get it.Thank you for any answer in advance.
There is in general no internal order to the records in a MySQL table. The only order which exists is the one you impose at the time you query. You typically impose that order using an ORDER BY clause. But there is a bigger design problem here. If you want to order the records by the time when they were inserted, then you should either add a dedicated column to your table which contains a timestamp, or perhaps make the id column auto increment.
If you want to go with the latter option, here is how you would do that:
ALTER TABLE demo_table MODIFY COLUMN id INT auto_increment;
Then, do your insertions like this:
INSERT INTO demo_table (name) VALUES ('Michael');
The database will choose an id value for the Michael record, and in general it would be greater than any already existing id value. If you need absolute control, then adding a timestamp column might make more sense.
Just add another Column Created (Timestamp) in your table to store the time of insertion
Then use this Command for insertion
insert into demo_table id, name,created values(4,"Michael",NOW())
The NOW() function returns the current date and time.
Since you are recording the timestamp, it can be also used for future reference too
It's not clear why you want to control the "order" in which the data is stored in your table. The relational model does not support this; unless you specify an order by clause, the order in which records are returned is not deterministic.. Even if it looks like data is stored in a particular sequence, the underlying database engine can change its mind at any point in time without breaking the standards or documented behaviours.
The fact you observe a particular order when executing a select query without order by is a side effect. Side effects are usually harmless, right up to the point where the mean feature changes and the side effect's behaviour changes too.
What's more - it's generally a bad idea to rely on the primary key to have "meaning". I assume your id column represents a primary key; you should really not rely on any business meaning in primary keys - this is why most people use surrogate keys. Depending on the keys indicating in which order a record was created is probably harmless, but it still seems like a side effect to me. In this, I don't support #TimBiegeleisen's otherwise excellent answer.
If you care about the order in which records were entered, make this explicit in the schema by adding a timestamp column, and write your select statement to order by that timestamp. This is the least sensitive to bugs or changes in the underlying logic/database engine.

Dynamic value to display numbers of entries in second table

I've got multiple entries in table A and would like to display the number of entries in a coloumn of table B. Is there a way to create a dynamic cell-content displaying the number of entries in a table?
I'm a beginner in MySQL and did not find a way to do it so far.
Example table A:
+----+------+------------+
| id | name | birthday |
+----+------+------------+
| 1 | john | 1976-11-18 |
| 2 | bill | 1983-12-21 |
| 3 | abby | 1991-03-11 |
| 4 | lynn | 1969-08-02 |
| 5 | jake | 1989-07-29 |
+----+------+------------+
What I'd like in table B:
+----+------+----------+
| id | name | numusers |
| 1 | tblA | 5 |
+----+------+----------+
In my actual database there is no incrementing ID so just taking the last value would not work - if this would've been a solution.
If MySQL can't handle this the option would be to create some kind of cronjob on my server reading the number of rows and writing them into that cell. I know how to do this - just checking if there's another way.
I'm not looking for a command to run on the mysql-console. What I'm trying to figure out is if there's some option which dynamically changes the cell's value to what I've described above.
You can create a view that will give you this information. The SQL for this view is inspired by an answer to a similar question:
CREATE VIEW table_counts AS
SELECT table_name, table_rows
FROM information_schema.tables
WHERE table_schema = '{your_db}';
The view will have the cells you speak of. As you can see, it is just a filter on an already existing table, so you might consider that this table information_schema.tables is the answer to your question.
You can do that directly with COUNT() for example SELECT COUNT(*) FROM TblA The you get all rows from that table. If you IDXs are ok then its very fast. If you write it to another table you have to make an request too to get the result of the second table. So i think your can do it directly.
If you have some performance problems there are some other possibilities like Triggers or Stored Procedures to calculate that result and save them in a memory table to get a better performance.

Average a difference in timestamps across all rows

I have a table that looks like so:
id | username | jointime | parttime
------------------------------------------
1 | foo | 1391806818 | 1391814383
2 | bar | 1391406218 | 1392714270
3 | baz | 1391327818 | 1393197383
4 | qux | 1391815603 | 1391818320
I would like to find the overall average time that's being spent on the site (parttime - jointime).
I tried a query like the one below, but it just returned the average time spent by one single user.
SELECT AVG(parttime - jointime) as time FROM foo_table
Any ideas as to how I can get the overall average difference?
Thanks
You are already getting what you want.
Using your example data, result is:
796974.75
http://sqlfiddle.com/#!2/d94977/1/0
That is the average of the 4 differences in your example data:
7565
1308052
1869565
2717
http://sqlfiddle.com/#!2/d94977/2/0
It is not the average of one particular user, but indeed the average of all sessions (stored on the table), which I believe is what you want.
Wrap that in a SUM.
SELECT SUM(AVG(parttime - jointime)) as time FROM foo_table

Auto Increment mysql trigger

How create a Auto increment field based on this example:
I have this table, with "AF" field, in that format: SN.MM.YYYY
The "SN" = AI number based on last insert, MM= Atual Month, YYYY = Atual Year.
| ID | AF |
____________________
| 1 | 01.10.2013 |
| 2 | 02.10.2013 |
So, when changes the month or year, the trigger must set "AF" field that way:
Ex.: Month changes to November(Reset SN to 01).
| 3 | 01.11.2013 |
| 4 | 02.11.2013 |
The same thing when year changes(Reset SN to 01):
| 5 | 01.01.2014 |
| 6 | 02.01.2014 |
| 7 | 03.01.2014 |
Anyone know's how set that trigger?
Obs: There may be more than one record in one day, so, day is not important.
Sorry for the bad english
Thanks guys!
Technically you can do something like this
CREATE TRIGGER tg_bi_table1
BEFORE INSERT ON table1
FOR EACH ROW
SET NEW.af = CONCAT(
LPAD(COALESCE(
(SELECT MAX(LEFT(af, 2))
FROM table1
WHERE af LIKE DATE_FORMAT(CURDATE(), '__.%m.%Y')), 0) + 1, 2, '0'),
DATE_FORMAT(CURDATE(), '.%m.%Y'));
Here is SQLFiddle demo
Note: This approach (creating your own ago_increment values with such a pattern) has two major drawbacks:
Under heavy concurrent access different connections may obtain the same AF number
Because of your particular AF pattern (SN comes first) using an index is impossible therefore you'll end up always getting a full scan

MySQL - COUNT before INSERT in one query

Hey all, I am looking for a way to query my database table only once in order to add an item and also to check what last item count was so that i can use the next number.
strSQL = "SELECT * FROM productr"
After that code above, i add a few product values to a record like so:
ID | Product | Price | Description | Qty | DateSold | gcCode
--------------------------------------------------------------------------
5 | The Name 1 | 5.22 | Description 1 | 2 | 09/15/10 | na
6 | The Name 2 | 15.55 | Description 2 | 1 | 09/15/10 | 05648755
7 | The Name 3 | 1.10 | Description 3 | 1 | 09/15/10 | na
8 | The Name 4 | 0.24 | Description 4 | 21 | 09/15/10 | 658140
i need to count how many times it sees gcCode <> 'na' so that i can add a 1 so it will be unique. Currently i do not know how to do this without opening another database inside this one and doing something like this:
strSQL2 = "SELECT COUNT(gcCode) as gcCount FROM productr WHERE gcCode <> 'na'
But like i said above, i do not want to have to open another database query just to get a count.
Any help would be great! Thanks! :o)
There's no need to do everything in one query. If you're using InnoDB as a storage engine, you could wrap your COUNT query and your INSERT command in a single transaction to guarantee atomicity.
In addition, you should probably use NULL instead of na for fields with unknown or missing values.
They're two queries; one is a subset of the other which means getting what you want in a single query will be a hack I don't recommend:
SELECT p.*,
(SELECT COUNT(*)
FROM PRODUCTR
WHERE gccode != 'na') AS gcCount
FROM PRODUCTR p
This will return all the rows, as it did previously. But it will include an additional column, repeating the gcCount value for every row returned. It works, but it's redundant data...