Need some help.
I have got 3 tables. klients, klientwithservice, service.
table klients
id | klientrnd
---------
1 | 11231231
2 | 22222222
table service
id | servicename
---------
1 | Repair laptop
2 | Repair pc
table klientwithservice
id | klientrnd | serviceid
-------------------------------
1 | 11231231 | 1
2 | 11231231 | 2
3 | 22222222 | 1
4 | 22222222 | 2
I need to output SERVICENAME instead ID.
My sql query is:
SELECT serviceid FROM klientwithservice WHERE '$pole8' = `klientrnd`
Where $pole8 = klientrnd exactly person on which page i placed.
for this you need to JOIN two table
use below query
SELECT s.servicename FROM klientwithservice as kws
JOIN service as s ON s.id = kws.serviceid
WHERE `klientrnd` = '$pole8'
Firstly your sql SELECT serviceid FROM klientwithservice WHERE '$pole8' = klientrnd is wrong.
It will return a syntax error stating the unknown column $pole8 (it's exact value) `is wrong
Second you should use join to achieve what you're after. Try this:
SELECT s.servicename FROM klientwithservice as k
JOIN service as s ON s.id = k.serviceid
WHERE k.klientrnd = '$pole8'
Related
I am looking for a way to get groups of the GROUP_CONCAT() function in a single query, for example.
My current code
SELECT
SUBSTRING_INDEX(GROUP_CONCAT(service_info.ip_address SEPARATOR ','),',',service_plans.aggregation) AS ip_address
FROM
services
LEFT JOIN
service_info
ON
service_info.service_id = services.id
LEFT JOIN
service_plans
ON
service_plans.id = services.service_plan_id
WHERE
service_plans.id = '2'
I want to group the IP addresses by a specific number(the $group_by variable if you see in the query) but then separate by a different character such as ":" or something.
Essentially I want my output to look like:
If $group_by=2: 10.1.1.2,10.1.1.3:10.1.1.4,10.1.1.5
If $group_by=3: 10.1.1.2,10.1.1.3,10.1.1.4:10.1.1.5
Is this possible to implement into my current query?
UPDATE: table structure
Table service_plans
id | name | aggregation
-----------------------------------------
1 | Uncapped 10Mbps 20:1 | 20
2 | Uncapped 20Mbps 10:1 | 10
3 | Capped 30Mbps | 0
Table services
id | service_plan_id | description
------------------------------------
1 | 2 | Phone
2 | 2 | Laptop
3 | 2 | PC
4 | 2 | TV
5 | 2 | Test
Table service_info
id | service_id | ip_address
------------------------------
1 | 1 | 10.1.1.2
2 | 2 | 10.1.1.3
3 | 3 | 10.1.1.4
4 | 4 | 10.1.1.5
5 | 5 | 10.1.1.6
I am trying to get an array of ip_address's concatenated and separated by a comma but the in groups of however much the service_plans.aggregation value is.
If aggregation is 2, then my output should be:
10.1.1.2,10.1.1.3:10.1.1.4,10.1.1.5
As you can see they are in groups of 2 and then the next group is separated by a colon(:)
If aggregation is 3, then my output should be:
10.1.1.2,10.1.1.3,10.1.1.4:10.1.1.5
As you can see they are in groups of 3 and then the next group is separated by a colon(:) and so on
Your post is a little confusing. What would be helpful is if you posted sample data, and then posted what you want your query to return. I'll give you an answer to what I think you're asking, based on the subject of your post.
ServicePlanIPs
service_plan_id | ip_address
-------------------------------
1 | 192.168.70.1
1 | 192.168.70.2
1 | 192.168.70.3
2 | 192.168.70.4
2 | 192.168.70.5
2 | 192.168.70.6
If you run this query against ServicePlanIPs:
SELECT service_plan_id, GROUP_CONCAT(ip_address) as ip_addresses
FROM ServicePlanIPs
GROUP BY service_plan_id
You will get:
service_plan_id | ip_addresses
-------------------------------
1 | 192.168.70.1, 192.168.70.2, 192.168.70.3
2 | 192.168.70.4, 192.168.70.5, 192.168.70.6
I don't guarantee this will run out of the box, but it should get you on the right track. Hope it helps. Note - if you're using a version of mysql which supports window functions, you can do something similar to the below and use the natively supported RANK function instead of doing it manually with variables.
SET #curRank := 0;
SET #concatIps := '';
SELECT
sp.id,
#curRank := #curRank + 1 AS rank,
IF(MOD(#curRank, (SELECT aggregation FROM service_plans WHERE id = {service_plan_id}) = 0, #concatIps := CONCAT(#concatIps, ':', s.ip_address), #concatIps := CONCAT(#concatIps, ',', s.ip_address))
FROM service_plans sp
JOIN services s
ON sp.id = s.service_plan_id
JOIN service_info si
ON si.service_id = s.id
WHERE sp.id = {service_plan_id}
ORDER BY service_info_id
I have been learning PHP and MySQL for a project and I am struggling with this part. For simplicity sake, I will only list the relevant fields (actually many more in real db) let's say I have 3 tables.
Table1
---------------------
Index | Name | email
1 | Rob | rob#email.com
2 | Kevin| kevin#email.com
3 | Amy | amy#email.com
Table2
------------------------
id | Info | Submitted
1 | Blah | 0
2 | Yada | 1
Table 3
-------------------------
id | Goal |Submitted
1 | 1 | 1
1 | 2 | 1
1 | 3 | 1
1 | 4 | 0
1 | 5 | 0
3 | 1 | 0
3 | 3 | 1
3 | 4 | 1
So, Table1 holds user information and is kinda the main table
Table2 the user inputs some data in a field and then submits for approval when ready. (I will be using the value of Submitted for functions later)
If the user has not submitted the info, there is not record. This is a 1 to 1 with Table1
Table3 The user inputs information for 5 goals. At any given time there could be 0 to max 5 goals entered for a user. The Submitted is the same for later processing. This table is Many to one with Table1. The Goal field literally shows the number 1 through 5, there is a separate field that holds the goal text, just not needed in this example.
Desired output is HTML table
Name | email | info |Goal1|Goal2|Goal3|Goal4|Goal5|
Rob | rob#email.com | Blah | 1 | 2 | 3 | 4 | 5 |
Kevin | kevin#email.com | Yada | | | | | |
Amy | amy#email.com | | 1 | | 3 | 4 | |
Not sure if the blanks are considered NULL or something else as they do not exist in the DB. I would like to put something in the field like an *. Basically the Submitted will be used for code to make the fields hyper links, so they need to be part of the query, just not in the table display, but if it would help, it can be displayed.
Name | email | info |Goal1|Goal2|Goal3|Goal4|Goal5|
Rob | rob#email.com | Blah | 1 | 2 | 3 | 4 | 5 |
Kevin | kevin#email.com | Yada | * | * | * | * | * |
Amy | amy#email.com | * | 1 | * | 3 | 4 | * |
I am using a query with left joins and group_concat, but that is not working well with the non existent data, and I cannot figure out how to include the Submitted field without doing some crazy concatenation, then pulling in all apart to put in the HTML fields.
I can include some code, but it might be hard to follow as there are lots of variables being used.
The best I have gotten out using only table1 and table3:
Rob 1,2,3,4,5
Kevin
Amy 1,3,4
With the records that have not been entered not be accounted for, it makes it near impossible to turn the data string into a table. If I can get something showing for every position, even if it does not exist yet, I do know how to make it into the html table.
I hope this makes sense and someone can help me with this.
As you stated that you have at most 5 goals. The best possible option is to use following query.
SELECT t1.Name,t1.email
,CASE WHEN t2.Info IS NULL THEN * ELSE t2.Info END as Info
,CASE WHEN g1.Goal IS NULL THEN * ELSE g1.Goal END as Goal1
,CASE WHEN g2.Goal IS NULL THEN * ELSE g2.Goal END as Goal2
,CASE WHEN g3.Goal IS NULL THEN * ELSE g3.Goal END as Goal3
,CASE WHEN g4.Goal IS NULL THEN * ELSE g4.Goal END as Goal4
,CASE WHEN g5.Goal IS NULL THEN * ELSE g5.Goal END as Goal5
FROM Table1 as t1
LEFT JOIN Table2 as t2 ON t2.id = t1.Index
LEFT JOIN Table3 as g1 ON g1.id = t1.Index AND g1.Goal=1
LEFT JOIN Table3 as g2 ON g2.id = t1.Index AND g2.Goal=2
LEFT JOIN Table3 as g3 ON g3.id = t1.Index AND g3.Goal=3
LEFT JOIN Table3 as g4 ON g4.id = t1.Index AND g4.Goal=4
LEFT JOIN Table3 as g5 ON g5.id = t1.Index AND g5.Goal=5
You will want to JOIN each of the tables together, and GROUP BY the user.
One way of handling the goals would be to display it as one column, containing all goals.
This should help you get started:
SELECT name,
email,
info,
<LOGIC> as goals
FROM table1
JOIN table2 ON table2.user_id = table1.id
JOIN table3 ON table3.user_id = table1.id
GROUP BY name
The logic that you use for the goals column could be created with a mixture of CASE and CONCAT (if a goal is defined, concatenate it into a string, and display that string as the final value of goals).
I'm trying to do return results from one table based on multiple results on another. Here's the setup:
Table A: "accounts"
id | fname | other_id
1 | test | 500
2 | test2 | 505
3 | test3 | 500
4 | test4 | 540
5 | test5 | 500
Table B: "transactions"
id | account_id |
1 | 1
2 | 4
3 | 2
4 | 1
5 | 3
6 | 2
What I'm trying to accomplish is, return all id's from transactions where account_id = the id in table A WHERE other_id = a certain value.
To do write it out manually it would look like this:
So for example if other_id = 500.
1) get records from accounts where other_id = 500 (will be multiple results, in this case, 1, 3 and 5)
2) get records from transactions where account_id = 1 OR account_id = 3 OR account_id = 5
I've tried a few different subselects but can't seem to come up with what I'm looking for.
I of course could just break this up into a loop using PHP but I'd rather use a single query for efficiency.
No subselect required, just a simple join.
select * from accounts a, transactions t where t.account_id=a.id and other_id=500
select t.id
from accounts as a
inner join transactions as t on a.id = t.account_id
where a.other_id=500
If i understand you right, you want this.
SELECT b.id
FROM accounts AS a
LEFT JOIN transactions AS b ON b.account_id = a.id
WHERE other_id = 500
Now I have 2 tables
STUDENT:
STUDENT_ID | STUDENT_NAME | COURSE_ID
1000 | Anson | 1
1001 | Jnson | 1
1002 | Andy | 2
1003 | Alex | 3
COURSE:
COUSE_ID | COURSE_NAME
1 | P5A
2 | P5B
3 | P5C
Now I would like to produce the result to show the students name in each class
Idea result:
P5A P5B P5C
Anson Andy Alex
Jason
what should I do, I am using php + mysql to build web system
select * from course c left join student s on c.course_id = s.course_id
order by c.course_name, c.course_id
Enumerate the result set. Each time course_id changes, start a new section.
I have two tables in MySQL:
Table entry:
id | name | date
1 | Test Entry | 12/12/2013
2 | Test Entry 2 | 12/12/2013
Table note
id | entry_id | name | value
1 | 1 | note1 | value1
2 | 1 | note2 | value2
3 | 2 | note1 | value1
4 | 3 | note4 | value4
Where entry_id in note is a foreign key to id in entry.
Is there any solution I can create with a SELECT that will give me a result like the following?
entry_id | name | note1 | note2 | note3
1 | Test Entry | value1 | value2 | -
2 | Test Entry 2 | value 1 | - | value3
I want to avoid LEFT JOIN here (current implementation is working like this) and want to join note only once if that is possible. LEFT JOIN is not good here, because I do not know how many notes can be attached to one entry. My current implementation works that way that I first fetch all distinct notes by name that can be found in note, and then build a SELECT with foreach through PHP. Finally, the SELECT statement looks like this:
SELECT
E.id as entry_id,
E.name as name,
N1.value as note1_value,
N2.value as note2_value,
N3.value as note3_value
FROM entry E
JOIN LEFT note N1 ON E.id = N1.entry_id AND N1.name = 'note1'
JOIN LEFT note N2 ON E.id = N2.entry_id AND N2.name = 'note2'
JOIN LEFT note N3 ON E.id = N3.entry_id AND N3.name = 'note3'
Things get tricky when I join on note 20-30 times.
No, there is not a way to do that without joins.
I would recommend doing 2 queries.
select * from entry where id = id
select * from note where entry_id = id
and then join the results in your application code. You're right, the left joins are going to be bad.
Best would be to use a table with one note value and a note type (number) per each line.
id | value | note_no
Like this you can use as much notes as you like.
You can get the notes on one line using group_concat.
For an example, see here: http://lietoservetruth.wordpress.com/2010/12/13/mysql-group_concat-vertival-concat-concat-records/
This is faster than asking DB twice, and it's better DB design...