Refer between cells in LibreOffice Calc - libreoffice

This is my LibreOffice Calc sheet, now I want to sort the ID in order of the RandomNum column. Now I want my sheet to fill the last Fullname column with the name of the person with the id from the first Fullname column. I hope someone understands what I want to do...
I want to refer the Fullname to its ID to keep this to together even if I resort.
Before sorting by RandomNum
| ID | Fullname | RandomNum | ID | Fullname (Fullname filled by first ID)
-------------------------------------------
| 1 | Jon Doe | 0.0003 | 1 | Jon ...
-------------------------------------------
| 2 | Jane Doe | 0.0001 | 2 | Jane ...
-------------------------------------------
| 3 | Lee Bee | 0.0002 | 3 | Lee ...
-------------------------------------------
After sorting by RandomNum
| ID | Fullname | RandomNum | ID | Fullname (Fullname filled by first ID)
-------------------------------------------
| 1 | Jon Doe | 0.0001 | 2 | Jane ...
-------------------------------------------
| 2 | Jane Doe | 0.0002 | 3 | Lee ...
-------------------------------------------
| 3 | Lee Bee | 0.0003 | 1 | Joe ...
-------------------------------------------

Related

Query table with array_agg of ALL previous positions, excluding current position

I have a database table with:
id | date | position | name
--------------------------------------
1 | 2016-06-29 | 9 | Ben Smith
2 | 2016-06-29 | 1 | Ben Smith
3 | 2016-06-29 | 5 | Ben Smith
4 | 2016-06-29 | 6 | Ben Smith
5 | 2016-06-30 | 2 | Ben Smith
6 | 2016-06-30 | 2 | Tom Brown
7 | 2016-06-29 | 4 | Tom Brown
8 | 2016-06-30 | 2 | Tom Brown
9 | 2016-06-30 | 1 | Tom Brown
How can I query the table efficiently so that I can get a new column using array_agg().
I have already tried the following query however its incredibly slow and also wrong as it doesn't group the previous_positions by the name column:
SELECT
j.*,
(SELECT array_agg(id) FROM jockeys j2 WHERE j2.id < j.id)
FROM jockeys j
I expect the table output to look like this
id | date | position | name | previous_positions
----------------------------------------------------------
1 | 2016-06-29 | 9 | Ben Smith | {}
2 | 2016-06-29 | 1 | Ben Smith | {9}
3 | 2016-06-29 | 5 | Ben Smith | {9,1}
4 | 2016-06-29 | 6 | Ben Smith | {9,1,5}
5 | 2016-06-30 | 2 | Ben Smith | {9,1,5,6}
6 | 2016-06-30 | 2 | Tom Brown | {}
7 | 2016-06-29 | 4 | Tom Brown | {2}
8 | 2016-06-30 | 2 | Tom Brown | {2,4}
9 | 2016-06-30 | 1 | Tom Brown | {2,4,2}
You may use the WINDOW clause for array_agg
SELECT
j.* , array_agg(position) over w as previous_positions
FROM jockeys j
WINDOW w as
( partition by name ORDER BY id rows between
unbounded preceding and 1 preceding
)
DEMO

Is there a V-lookup effect in Microsoft Access?

I am a novice self-teaching Microsoft Access.
I have an MS Access database with a table of students (Table1).
Table1
+----+-----------+----------+------------+------------+
| id | firstname | lastname | Year_Group | Form_Group |
+----+-----------+----------+------------+------------+
| 2 | mnb | nbgfv | 7 | 1 |
| 3 | jhg | uhgf | 8 | 2 |
| 4 | poi | ijuy | 9 | 2 |
| 5 | tgf | tgfd | 10 | 2 |
| 6 | wer | qwes | 11 | 2 |
+----+-----------+----------+------------+------------+
Every day students days are recorded sort of like Table2.
Table2
+----------+----+-----------+----------+------------+--------+-----------+----------+
| Date | id | firstname | lastname | Year_Group | Effort | Behaviour | Homework |
+----------+----+-----------+----------+------------+--------+-----------+----------+
| 28/02/19 | 2 | mnb | nbgfv | 7 | Good | Good | Y |
| 28/02/19 | 3 | jhg | uhgf | 8 | OK | OK | Y |
| 28/02/19 | 4 | poi | ijuy | 9 | Bad | Bad | N |
| 01/03/19 | 5 | tgf | tgfd | 10 | Good | OK | Y |
| 01/03/19 | 6 | wer | qwes | 11 | Good | Good | Y |
+----------+----+-----------+----------+------------+--------+-----------+----------+
Is there a way (when using a list box or combo box) to select a student from Table1 so that their information is used for the corresponding columns in Table2?
Or is there a more efficient way to do this?
Firstly, you should normalise your data.
Currently, you are repeating the firstname, lastname, and Year_Group data in two separate tables, which not only bloats your database, but also means that such data must be maintained in two separate places, potentially leading to inconsistencies and then uncertainty as to which is the master.
Instead, I would suggest that your Students table should contain all information pertaining to the characteristics of a student:
Students
+----+-----------+----------+------------+------------+
| id | firstname | lastname | Year_Group | Form_Group |
+----+-----------+----------+------------+------------+
| 2 | mnb | nbgfv | 7 | 1 |
| 3 | jhg | uhgf | 8 | 2 |
| 4 | poi | ijuy | 9 | 2 |
| 5 | tgf | tgfd | 10 | 2 |
| 6 | wer | qwes | 11 | 2 |
+----+-----------+----------+------------+------------+
And the information pertaining to each school day should only reference the student ID in the Students table:
SchoolDays
+----------+----+--------+-----------+----------+
| Date | id | Effort | Behaviour | Homework |
+----------+----+--------+-----------+----------+
| 28/02/19 | 2 | Good | Good | Y |
| 28/02/19 | 3 | OK | OK | Y |
| 28/02/19 | 4 | Bad | Bad | N |
| 01/03/19 | 5 | Good | OK | Y |
| 01/03/19 | 6 | Good | Good | Y |
+----------+----+--------+-----------+----------+
Then, if you want to display the data in its entirety, you would use a query which joins the two tables, e.g.:
select
t2.date,
t1.firstname,
t1.lastname,
t1.year_group,
t2.effort,
t2.behaviour,
t2.homework
from
students t1 inner join schooldays t2 on t1.id = t2.id

What is the proper approach to insert into multiple tables at once?

For example I have a table called product_list, which holds a list of products:
+----+-------+-----------+-------------+--+
| id | name | weight(g) | type | |
+----+-------+-----------+-------------+--+
| 1 | Shirt | 157 | Clothes | |
+----+-------+-----------+-------------+--+
| 2 | Ring | 53 | Accessories | |
+----+-------+-----------+-------------+--+
| 3 | Pants | 202 | Clothes | |
+----+-------+-----------+-------------+--+
and a table called product_price:
+----------+----+-------+--------+--+
| price_id | id | name | price | |
+----------+----+-------+--------+--+
| 1 | 1 | Shirt | 99.00 | |
+----------+----+-------+--------+--+
| 2 | 2 | Ring | 149.00 | |
+----------+----+-------+--------+--+
| 3 | 3 | Pants | 119.00 | |
+----------+----+-------+--------+--+
If I insert 1 row of data into product_list, part of the data (such as product_id & product name) should also be inserted in another table like product_price which holds the price for all products (new products would have 0 or NULL values for their price). Eg:
product_list:
+----+--------+-----------+-------------+--+
| id | name | weight(g) | type | |
+----+--------+-----------+-------------+--+
| 1 | Shirt | 157 | Clothes | |
+----+--------+-----------+-------------+--+
| 2 | Ring | 53 | Accessories | |
+----+--------+-----------+-------------+--+
| 3 | Pants | 202 | Clothes | |
+----+--------+-----------+-------------+--+
| 4 | Shirt2 | 175 | Clothes | |
+----+--------+-----------+-------------+--+
product_price:
+----------+----+-------+--------+--+
| price_id | id | name | price | |
+----------+----+-------+--------+--+
| 1 | 1 | Shirt | 99.00 | |
+----------+----+-------+--------+--+
| 2 | 2 | Ring | 149.00 | |
+----------+----+-------+--------+--+
| 3 | 3 | Pants | 119.00 | |
+----------+----+-------+--------+--+
| 4 | 4 | Shirt2| 0.00 | |
+----------+----+-------+--------+--+
My question here is the method in approaching this. What is the proper way (in a professional manner) would an experienced person approach this matter?
These are 2 approaches I have in mind:
1 - Using triggers to insert into the other tables like product_price,etc whenever I insert a product data into product_list
2 - Using a function (stored procedure) like product_add to add a new product into each tables.
Which method is better? Or if there a better suggestion, then I'd like to know about it. Thanks in advance.
TLDR: Should I use Triggers or instead use Stored Procedures, which is better? Or you have a better suggestion?
In Postgres, you can use CTEs:
with pl as (
insert into product_list(name, weight, type)
select . . .
returning *
)
insert into product_price(id, price)
select id, NULL
from pl;
Note: You shouldn't repeat the name column in the product_list and product_price table. It should only be in the list table.

postgresql condition column name = data

I have three tables.
table a
| uid | name | number |
|-----+---------+--------|
| 1 | table | 1 |
| 2 | chair | 2 |
table b
| uid | name | number |
|-----+---------+--------|
| 1 | john | 1 |
| 2 | billy | 0 |
| 3 | bob | 2 |
| 4 | sally | 1 |
table c
| uid | table a | john | billy | bob | sally |
|-----+---------+--------+--------+-------|-------|
| 1 | table | T | | | T |
| 2 | chair | | | C | |
What I need to be able to do is look at the column names in table c, find the corresponding row entry in table b and if the numbers are the same as the numbers from table a, then set the table c value to T. Otherwise set it to C. This needs to be triggered whenever either table a or table b are updated.
How can I write an update the table using if or case statement.
Thanks.

MS Access Group By breaks when using a date

For some reason using a date/time field in a select query with Group By in Access 2010 breaks (records are not properly "grouped by" the text field first, showing the same "aTextField" value multiple times). I am able to replicate the issue in a simple, one table query. Ex:
SELECT aTextField, SUM(aIntField) AS SumOfaIntField
FROM simpleTable
GROUP BY aTextField, aDateField
HAVING aDateField >= Date()
ORDER BY aTextField;
As soon as you remove the "aDateField" from the query (Group By and Having lines) then it works properly. I can even remove the HAVING line and it still breaks. Leaving me to believe that it is something with the Group By.
Any feedback would be great. Thanks!
EDIT More details
**simpleTable**
--------------------------------------------
| ID | aTextField | aIntField | aDateField |
============================================
| 1 | John Doe | 1 | 3/14/2013 |
| 2 | John Doe | | 3/15/2013 |
| 3 | Jane Doe | 1 | 3/15/2013 |
| 4 | John Doe | 2 | 3/18/2013 |
| 5 | Jane Doe | 1 | 3/19/2013 |
| 6 | John Doe | | 3/20/2013 |
| 7 | John Doe | 3 | 3/21/2013 |
| 8 | Jane Doe | 1 | 3/19/2013 |
| 9 | John Doe | | 3/22/2013 |
| 10 | Jane Doe | 2 | 3/20/2013 |
| 11 | Jane Doe | | 3/21/2013 |
| 12 | Jane Doe | | 3/22/2013 |
--------------------------------------------
**Expected Result**
-------------------------------
| aTextField | SumOfaIntField |
===============================
| Jane Doe | 4 |
| John Doe | 3 |
-------------------------------
**Actual Result**
-------------------------------
| aTextField | SumOfaIntField |
===============================
| Jane Doe | 2 |
| Jane Doe | 2 |
| Jane Doe | |
| Jane Doe | |
| John Doe | |
| John Doe | 3 |
| John Doe | |
-------------------------------
So what appears to be happening is that there is a seperate row for each date as well. I just need to filter by the date and not necessarily Group By it. However, Access will not accept the query without grouping it. Options?
You're grouping by aTextField and aDateField. Perhaps simpleTable includes rows where the date is the same, but the time of day is different. In that case your grouping would produce a row for each date/time combination.
Whether or not that was the explanation, you should check what the db engine actually evaluates by including aDateField in the SELECT list.
SELECT aTextField, aDateField, SUM(aIntField)
FROM simpleTable
GROUP BY aTextField, aDateField
HAVING aDateField >= Date()
ORDER BY aTextField;
Also consider using a WHERE instead of HAVING clause:
WHERE aDateField >= Date()
Based on your sample data, I suspect you want ...
SELECT aTextField, SUM(aIntField)
FROM simpleTable
GROUP BY aTextField
WHERE aDateField >= Date()
ORDER BY aTextField;
You should be able to use the following:
SELECT aTextField, SUM(aIntField) AS SumOfaIntField
FROM simpleTable
WHERE aDateField >= Date()
GROUP BY aTextField
ORDER BY aTextField;
You will notice that I removed the GROUP BY on the aDateField column. Since you want the total for each aTextField, then you do not need to group by the date. Grouping by date will result in a separate row for each distinct date.
Note: this query was tested in MS Access 2010 and generated your desired result.
I think you are misunderstanding on how GROUP BY works. You should be seeing the same aTextField once for each unique textfield/datetime combination
Sample
a 2012-01-01
a 2012-01-01
b 2012-01-01
b 2012-01-02
b 2012-01-02
group by aTextField, aDateField
a 2012-01-01
b 2012-01-01
b 2012-01-02
group by aTextField
a
b