Is it possible to generate (join) a new field by combining existing fields as source ?
I have a table like this:
id | title | parent_id | path
1 | a | 0 | 1
2 | b | 1 | 1/2
3 | c | 1 | 1/3
4 | d | 3 | 1/3/4
I want to use the "path" field's string (numbers) as a kind of index and generate (join) a new field using titles insead ids like:
id | title | parent_id | path | title_path
1 | a | 0 | 1 | a
2 | b | 1 | 1/2 | a/b
3 | c | 1 | 1/3 | a/c
4 | d | 3 | 1/3/4| a/c/d
Is this possible using sql on itself or should I use php for this?
Related
This question already has an answer here:
MySQL pivot row into dynamic number of columns
(1 answer)
Closed 3 years ago.
Say I have a table like so
+----+----------+------+
| id | name | type |
+----+----------+------+
| 1 | apple | F |
| 1 | pear | F |
| 1 | cucumber | V |
| 2 | orange | F |
| 2 | grass | NULL |
| 2 | broccoli | V |
| 3 | flower | NULL |
| 3 | tomato | NULL |
+----+----------+------+
I want to end up with a table that counts the number of elements for each type (including NULL types) AND for each id, like this:
+----+-----------------+--------------+--------------+
| id | type_NULL_count | type_F_count | type_V_count |
+----+-----------------+--------------+--------------+
| 1 | 0 | 2 | 1 |
| 2 | 1 | 1 | 1 |
| 3 | 2 | 0 | 0 |
+----+-----------------+--------------+--------------+
This is rather easy to do, but is there a way (a query I can write or something else) such that when I go back and edit one of the type fields in the first table, I end up with a properly updated count table?
For example, let's say I want to add a new type (type X) and change the type field for flower from NULL to X. Is there a way to end up with the following table without having to rewrite the query or add more statements?
+----+-----------------+--------------+--------------+--------------+
| id | type_NULL_count | type_F_count | type_V_count | type_X_count |
+----+-----------------+--------------+--------------+--------------+
| 1 | 0 | 2 | 1 | 0 |
| 2 | 1 | 1 | 1 | 0 |
| 3 | 1 | 0 | 0 | 1 |
+----+-----------------+--------------+--------------+--------------+
I'm not sure if this is the best way to do this, so I am open to suggestions
Having a secondary table which it's number of columns changes based on your first table is not a viable option.
Do you need to keep the result in a table or it will be displayed as a report?
I think a better way to do this is using the SQL below calculate counts by id plus type and display using your data display tool the way you like it.
select id, type, count(*) count
from d
group by 1,2
order by 1,2
The output would be
id type count
1 F 2
1 V 1
2 F 1
2 V 1
2 1
3 X 1
3 1
I'm trying to break up a SQL table that needs to take a users name and find the unique user ID's from up to 4 systems.
The data is currently like this:
| Name | User_ID |
-----------------
| A | 10 |
| A | 110 |
| A | 1500 |
| A | 4 |
| B | 20 |
| B | 100 |
| B | 2 |
| C | 10 |
I need to pivot it around the user's name to look like this (the id's don't need to be in numerical order as the SYS#_ID for each doesn't matter):
| Name | SYS1_ID | SYS2_ID | SYS3_ID | SYS4_ID |
------------------------------------------------
| A | 4 | 10 | 110 | 1500 |
| B | 2 | 20 | 100 | NULL |
| C | 10 | NULL | NULL | NULL |
This is the code I have tried on MySQL:
PIVOT(
COUNT(User_ID)
FOR Name
IN (SYS1_ID, SYS2_ID, SYS3_ID, SYS4_ID)
)
AS PivotedUsers
ORDER BY PivotedUsers.User_Name;
I'm unsure if PIVOT works on MySQL as I keep getting an error "PIVOT unknown". Is there a way to find the values that each user has and if they do not appear in the table already add them to the next column with a max of 4 values?
I would like to calculate average from nested relationship between eloquent models. So, let's say, I have 3 tables called programs, activities and statistics.
For simplicity sake, I will try to minimize the structure as follows:
program table:
-------------
| id | name |
-------------
| 1 | Foo |
| 2 | Bar |
-------------
activities table:
-----------------------------------
| id | program_id | name |
-----------------------------------
| 1 | 1 | Foo 1 |
| 2 | 1 | Foo 2 |
| 3 | 1 | Foo 3 |
| 4 | 2 | Bar 1 |
| 5 | 2 | Bar 2 |
-----------------------------------
statistics table:
-----------------------------------
| id | activity_id | type | score |
-----------------------------------
| 1 | 1 | A | 25 |
| 2 | 1 | B | 20 |
| 3 | 1 | A | 22 |
| 4 | 2 | A | 27 |
| 5 | 2 | B | 24 |
| 6 | 3 | A | 23 |
-----------------------------------
Now, what I want to get is the average of score of a program with specific type of statistic. I defined relationship in models, and tried following code, but no avail:
$program = Program::find(1);
$avg = $program->activities->where('statistics.type', 'A')->avg('statistics.value');
$avg always 0 or null if there is no activities in program, even without where clause.
i'm sure that i defined the relationship correctly because $program->activities returns a sets of activities and $activity-> statistics return a sets of statistics as well.
Any ideas?
You can use whereHas() like this:
Statistics::whereHas('activity', function ($q) use($programId) {
$q->where('program_id', $programId);
})
->where('type', 'A')
->avg('score');
Make sure you've defined activity relationship which should be "statistics belongsTo() activity".
I have table :
id | name
1 | a,b,c
2 | b
in another table i want like this :
id | parent | name
1 | 1 | a
2 | 1 | b
3 | 1 | c
4 | 2 | b
Please help me how to get it done in MySQL
I've got two tables in my database. Table 1 is a list of "timelines" and their corresponding owners and title.
Table 2 is a list of users who have access to the timelines but are followers, not owners.
I'm trying to write a query that outputs the lineID's and corresponding titles that are linked to a userID in either of the two tables.
A query for userID 1 would ideally output:
1 a
2 b
3 c
6 f
Hopefully this isn't too confusing but the purpose is to fill a dynamically generated select box with the LineID and Title for a given UserID...
Table 1 ("owners")
--------------------------
| LineID | UserID | Title |
| 1 | 1 | a |
| 2 | 1 | b |
| 3 | 1 | c |
| 4 | 2 | d |
| 5 | 2 | e |
| 6 | 1 | f |
--------------------------
Table 2 ("followers")
----------------------------
| RowID | LineID | UserID |
| 1 | 1 | 1 |
| 2 | 1 | 2 |
| 3 | 3 | 1 |
| 4 | 3 | 2 |
| 5 | 2 | 2 |
| 6 | 6 | 1 |
----------------------------
I tried using:
SELECT title
FROM `lines`
LEFT JOIN follow
ON follow.user_id = lines.user_id
WHERE follow.user_id = 1
That ended up producing duplicate rows.
The output I need would ideally be an array consisting of all the lineID's and Titles associated with that userID.
select LineId, Title
from owners
where LineId in (select LineId from followers group by LineId )
order by owners.LineId